Использование блоков внутри блоков в Objective-C: EXC_BAD_ACCESS

Используя iOS 5 новый TWRequest API, я столкнулся с кирпичной стеной, связанной с использованием блоков.

Что мне нужно сделать, так это, получив успешный ответ на первый запрос, немедленно запустить другой. В блоке завершения второго запроса я сообщаю об успешном или неудачном выполнении многоэтапной операции.

Вот примерно то, что я делаю:

- (void)doRequests
{
    TWRequest* firstRequest = [self createFirstRequest];
    [firstRequest performRequestWithHandler:^(NSData* responseData,
                                              NSHTTPURLResponse* response,
                                              NSError* error) {
        // Error handling hidden for the sake of brevity...
        TWRequest* secondRequest = [self createSecondRequest];
        [secondRequest performRequestWithHandler:^(NSData* a,
                                                   NSHTTPURLResponse* b,
                                                   NSError* c) {
            // Notify of success or failure - never reaches this far
        }];
    }];
}

Я не храню ни запросы, ни ссылки на них; это просто огонь и забыл.

Однако, когда я запускаю приложение, оно вылетает с EXC_BAD_ACCESS на:

[secondRequest performRequestWithHandler:...];

Он отлично выполняет первый запрос, но когда я пытаюсь запустить второй с обработчиком, он вылетает. Что не так с этим кодом?


Методы для создания запросов так же просто, как:

- (TWRequest*)createFirstRequest
{
    NSString* target   = @"https://api.twitter.com/1/statuses/home_timeline.json";
    NSURL* url         = [NSURL URLWithString:target];
    TWRequest* request = [[TWRequest alloc]
                          initWithURL:url parameters:params
                          requestMethod:TWRequestMethodGET];
    // _twitterAccount is the backing ivar for property 'twitterAccount',
    // a strong & nonatomic property of type ACAccount*
    request.account    = _twitterAccount;

    return request;
}

2 ответа

Решение

Убедитесь, что вы сохраняете ссылку / сохраняете ACAccountStore который владеет ACAccount вы используете для подписи TWRequests.

Если вы этого не сделаете, ACAccount станет недействительным, а затем вы получите EXC_BAD_ACCESS при попытке запустить TWRequest подписано с этим.

Я не знаком с TW*, так что посчитайте это диким предположением... попробуйте отправить выделенный из кучи блок:

[firstRequest performRequestWithHandler:[^ (NSData *responseData, ...) {
  ...
} copy]];

Чтобы уточнить, я думаю, что блок, который вы отправляете, выделен в куче, поэтому, хотя TW * может его сохранить, он не будет иметь никакого значения, если он уже вышел из области видимости.

Другие вопросы по тегам