iPhone EXC_BAD_ACCESS при доступе к экземпляру var в блоке - PullRequest
1 голос
/ 17 февраля 2012

У меня есть вопрос о переменных экземпляра в сочетании с блоками и дугой в Objective 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 ]

3 голосов
/ 17 февраля 2012

параметры очищаются 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" в течение всего срока службы блока

0 голосов
/ 17 февраля 2012

В вашем распоряжении есть только параметры блока, т.е. response, data и error в этом случае.Вы можете использовать [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);
...