Использование блоков внутри блоков в 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
вы используете для подписи TWRequest
s.
Если вы этого не сделаете, ACAccount
станет недействительным, а затем вы получите EXC_BAD_ACCESS при попытке запустить TWRequest
подписано с этим.
Я не знаком с TW*, так что посчитайте это диким предположением... попробуйте отправить выделенный из кучи блок:
[firstRequest performRequestWithHandler:[^ (NSData *responseData, ...) {
...
} copy]];
Чтобы уточнить, я думаю, что блок, который вы отправляете, выделен в куче, поэтому, хотя TW * может его сохранить, он не будет иметь никакого значения, если он уже вышел из области видимости.