NSThread在第二次通话时崩溃(iPhone)

时间:2009-02-03 16:18:53

标签: iphone objective-c cocoa cocoa-touch multithreading

我有一个对象,在该对象中我启动了我的线程(用于加载一些URL加载)。

当我返回数据时,我调用一个选择器在主线程上执行。

如果我第一次调用它,但第二次崩溃(没有特定错误),工作正常。

[NSThread detachNewThreadSelector:@selector(doThread:)
                         toTarget:self
                       withObject:@"lala"];

-(void) doThread:(NSString *)poststring {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


DataModelLocator *mydelegate = [DataModelLocator instance];
NSData *postData = [poststring dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSURL *url = [NSURL URLWithString:[mydelegate fwaservicepath]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

[request setURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[request setHTTPBody:postData];

NSURLResponse *urlResponse;

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:nil];

if(data) {
    [self performSelectorOnMainThread:@selector(loadDidFinishWithData:)
                           withObject:data 
                        waitUntilDone:YES];
    //[self loadDidFinishWithData:data];
} else {
    [self performSelectorOnMainThread:@selector(loadDidFinishWithError:)
                           withObject:data 
                        waitUntilDone:YES];
}
[pool release];

}
}

当我打电话给performSelectorOnMaintThread时它会崩溃......当它被释放时,它是否会在单身人身上崩溃?

2 个答案:

答案 0 :(得分:4)

处理线程时,请避免像瘟疫这样的自动释放对象。自动释放池将在不确定的时间排干,导致有趣的崩溃。对所涉及的所有对象使用alloc / init和release,确保使用performSelectorOnMainThread或detachNewThreadSelector保留您从另一个线程调用的方法中获取的所有对象。

Mac上的垃圾收集有效地解决了这些问题,但iPhone不会很快就会出现这种问题。

答案 1 :(得分:0)

您可能希望发布有关您的问题的更多信息(两条线路崩溃中的哪一条,到目前为止您从调试中发现的内容等),以便我们为您提供更好的建议。在不知道哪条线路给你带来问题的情况下,我会冒险猜测:从它的声音来看,你可能会有一个被自动垃圾收集清理干净的物体。

变量“数据”来自何处?如果您在头文件中将其创建为私有成员变量,则可能具有以下内容:

NSSomeType *data = [NSSomeType builtInInitFunction];

像这样初始化的变量通常会自动释放,但您可能希望确保垃圾收集保留该对象的实例。尝试类似:

// Objects initialized with init are retained
NSSomeType *data = [[NSSomeType alloc] init];

// Objects that would normally be autoreleased can be marked as retain
NSSomeType *data = [[NSSomeType builtInInitFunction] retain];

我不确定您的代码是如何构建的,但请务必为每个retain和init添加至少一个版本!我仍然是Objective-C的新手,所以它有点像领导盲人的盲人,所以接受我的劝告。

查看Learn Objective-C的“有关内存管理的更多信息”部分以获取更多信息。

EDIT2:澄清示例代码。感谢Evan(评论)的帮助。

编辑3:我同意布拉德的意见。考虑删除您自己处理alloc / init / release的AutoRelease池。我不太了解NSURLConnection对象知道这一点,但你的*数据内存被标记为Autorelease吗?如果是这样,您可能需要以不同的方式初始化或使用保留。

在调试器中逐步执行代码。找出A)确切地说哪条线崩溃,然后B)所有变量的值。如果你很幸运,你会注意到一个是零。