我在将NSNumber对象传递给不同的线程时遇到了一些麻烦。 我在viewDidload上调用一个函数,它将核心数据中的一些对象作为后台进程加载。它调用另一个函数循环加载的对象,以查看是否有与之相关的图像alredy下载。如果它不存在,则异步下载图像并在本地保存。问题是我需要在主线程上执行startDownloadFor:atIndex:但是由于传递的NSNumber对象,应用程序崩溃了。这是代码..
- (void)viewDidLoad {
...
...
[self performSelectorInBackground:@selector(loadImages) withObject:nil];
}
-(void)loadImages{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
...
...
[self fillInImages];
[pool release];
}
-(void)fillInImages{
NSString *imageURL;
for (int i=0; i < [dataManager.objectList count]; i++) {
...
if ([dataManager.RelatedImages Image] == nil) {
//[self startDownloadFor:imageURL atIndex:[NSNumber numberWithInt:i]; // << WORKS FINE
[self performSelectorOnMainThread:@selector(startDownloadFor:atIndex:) withObject:(imageURL, [NSNumber numberWithInt:i]) waitUntilDone:YES]; // << CRASHES
...
}else {
...
}
...
}
...
}
-(void)startDownloadFor:(NSString*)imageUrl atIndex:(int)indexPath{
NSString *indexKey = [NSString stringWithFormat:@"key%d",indexPath];
...
}
这样做的正确方法是什么?
由于
答案 0 :(得分:1)
我从未见过将多个对象传递给选择器的语法 - 是有效的objective-c代码吗?另外,在你的startDownloadFor:atIndex:你传入一个NSNumber,但该选择器上第二个参数的类型是(int) - 这可能不是很好;)
performSelectorOnMainThread的文档:说选择器应该只接受一个id类型的参数。你传递了一个无效的选择器,所以我认为它对NSNumber的位置感到非常困惑。
要修复它,请传递一个包含数字和图像URL的NSDictionary,即
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:imageURL, @"imageURL", [NSNumber numberWithInt:i], @"number", nil];
[self performSelectorOnMainThread:@selector(startDownload:) withObject:dict waitUntilDone:YES];
和
//-(void)startDownloadFor:(NSString*)imageUrl atIndex:(int)indexPath{
- (void)startdownload:(NSDictionary *)dict {
NSURL *imageURL = [dict objectForKey:@"imageURL"];
int indexPath = [[dict objectforKey:@"number"] intValue];
答案 1 :(得分:1)
您尝试将2个参数传递给performSelectorOnMainThread:withObject:waitUntilDone:
,而该方法仅支持传递一个参数。
您需要使用NSInvocation发送更多参数(或使用像院长提议的NSDictionary)。
SEL theSelector;
NSMethodSignature *aSignature;
NSInvocation *anInvocation;
theSelector = @selector(startDownloadFor:atIndex:);
aSignature = [self instanceMethodSignatureForSelector:theSelector];
anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
[anInvocation setSelector:theSelector];
[anInvocation setTarget:self];
// indexes for arguments start at 2, 0 = self, 1 = _cmd
[anInvocation setArgument:&imageUrl atIndex:2];
[anInvocation setArgument:&i atIndex:3];
[anInvocation performSelectorOnMainThread:@selector(invoke) withObject:NULL waitUntilDone:YES];