performSelectorInBackground上的EXC_BAD_ACCESS

时间:2013-11-08 07:42:56

标签: ios objective-c performselector

我想在后台调用此方法,

-(void)downloadImage_3:(NSString* )Path AtIndex:(int)i

我以这种方式打电话但它崩溃并显示EXC_BAD_ACCESS

[self performSelectorInBackground:@selector(downloadImage_3:AtIndex:) withObject:[NSArray arrayWithObjects:@"http://www.google.com",i, nil]];

如何在后台调用downloadImage_3:方法?

我在做错了吗?

3 个答案:

答案 0 :(得分:1)

您无法在@selector中调用参数化函数。创建NSDictionary,然后在withObject:

中传递该字典
int atIndex = 2; // whatever index you want to pass
NSArray *arr = [NSArray arrayWithObjects:obj1,obj2,nil];

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:atIndex],@"AtIndex",arr,@"ImagesUrl", nil];
[self performSelectorInBackground:@selector(downloadImage_3:) withObject:dictionary];

像这样定义downloadImage_3函数:

-(void)downloadImage_3:(NSDictionary *)dic {
    // use dic and write your code
}

答案 1 :(得分:1)

试试这个

[self performSelectorInBackground:@selector(downloadImage_3:AtIndex:) withObject:[NSArray arrayWithObjects:@"http://www.google.com",i, nil]  afterDelay:15.0];

或试试这个

NSString* number    =   [NSString stringWithFormat:@"%d",i];
NSArray* arrayValues    =   [[NSArray alloc] initWithObjects:[[msg_array objectAtIndex:i] valueForKey:@"Merchant_SmallImage"],number, nil];
NSArray* arrayKeys      =   [[NSArray alloc] initWithObjects:@"Path",@"Index",nil];
NSDictionary* dic   =   [[NSDictionary alloc] initWithObjects:arrayValues forKeys:arrayKeys];
[self performSelectorInBackground:@selector(downloadImage_3:) withObject:dic];

定义downloadImage_3函数,如下所示:

-(void)downloadImage_3:(NSDictionary *)dic 
{
   NSString *path = [dic valueForKey:@"Path"];
int i     = [[dic valueForKey:@"Index"] intValue];
  //Your code
}

答案 2 :(得分:0)

您不能将performSelectorInBackground:withObject:用于带有多个参数的选择器。建议其他答案给出了一些工作,但他们都假设你可以操纵你正在调用的方法,这并不总是可行的(或者甚至是清晰的好主意)。

我建议使用NSInvocation,因为它允许多个参数,或者使用GCD将块分派给后台队列(或者除此之外的任何队列)。

以下是NSInvocation的示例用法

NSMethodSignature *sig = [[self class] instanceMethodSignatureForSelector:@selector(downloadImage_3:AtIndex:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
[inv setTarget:self];
[inv setSelector:@selector(downloadImage_3:AtIndex:)];
[inv setArgument:(__bridge void *)@"http://www.google.com" atIndex:2];
NSUInteger i = 1;
[inv setArgument:&i atIndex:3];
[inv performSelectorInBackground:@selector(invoke) withObject:nil];

值得仔细检查,我在浏览器中编写了代码,所以我可能会错过编译器会接受的内容。

另外请注意,您应该重新考虑您的方法命名约定,一种更标准的命名方法方法是将该方法命名为-(void)downloadImage3:(NSString* )path atIndex:(int)i。请注意atIndex如何以小写开头,以及如何没有下划线(在方法名称中间看起来很奇怪)。另外值得注意的是,使用NSUInteger是索引的首选,因为NSArray通常适用于NSUIntegers(两者都应该有效,但有些情况下int可能不够)。