在访问块中的实例var时使用iPhone EXC_BAD_ACCESS

时间:2012-02-17 09:30:13

标签: iphone objective-c automatic-ref-counting block instance-variables

我有一个关于实例变量与块和组合的问题。目标C中的IOS5弧。

很快,当我访问此代码时,iPhone会给我一个EXC_BAD_ACCESS并终止:

- (void) doRequest: (void (^)(XMLTreeNode*) )completionHandler {
    NSString * urlString = [NSString stringWithFormat:@"blablaurl=%@&", action];

    for( NSString* key in parameters ){
        urlString = [urlString stringByAppendingFormat:@"&%@=%@", key, [parameters objectForKey:key]];
    }
    NSURL * url = [NSURL URLWithString:urlString];

    NSLog( @"Visiting: %@", [url absoluteString] );

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"GET"];

    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * response, NSData * data, NSError * err) {
            NSLog( @"Params=%@", parameters );
        completionHandler(e);
    }];
}

exc_bad_access发生在: NSLog(@“Params =%@”,参数);

(参数是类的实例变量)..刚刚在头文件中定义,没有特殊属性或者什么如此......

为什么会崩溃,我该如何防止它?谢谢!

我的猜测是崩溃,因为在doRequest调用之后对象的生命周期结束了,因此ARC清理所有变量(并使用参数var)。当urlconnection完成并调用块时,实例变量是清理干净..

2 个答案:

答案 0 :(得分:3)

参数由ARC清理。

这里有2个案例:

您的主对象在块完成之前未释放:只需为“参数”创建一个强大的非原子属性。使用属性中的“strong”关键字向ARC说,在所有主对象生命周期中需要“参数”

您的主对象在块完成之前被释放:创建一个指向对象的新__block指针

__block blockParameters = parameters;
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * response, NSData * data, NSError * err) {
    NSLog( @"Params=%@", blockParameters );
    completionHandler(e);
}];

使用“__block”关键字向ARC说你在整个块寿命期间需要“blockParameters”

答案 1 :(得分:0)

您只能使用块的参数,例如responsedataerror。您可以使用[response URL]来获取参数。

NSString *path = [[response URL] path];
NSString *secondPartOfURL = [[path componentsSeparatedByString:@"?"] objectAtIndex:1];
NSArray *keyValuePairs = [secondPartOfURL componentsSeparatedByString@´:@"&"];
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
for (NSString *pair in keyValuePairs) {
   NSArray *keyValue = [pair componentsSeparatedByString:@"="];
   [parameters setValue:[keyValue objectAtIndex:1] 
                 forKey:[keyValue objectAtIndex:0]];
}
NSLog(@"Params=%@", parameters);