Исчезающая ссылка на себя в блоке под ARC - PullRequest
1 голос
/ 26 октября 2011

У меня проблемы с выяснением, почему слабая ссылка на себя исчезает в следующем блоке.Следуя совету Дживы, найденному здесь http://blog.random -ideas.net /? P = 160 Я делаю __слабую ссылку на себя вне блока завершения, а затем делаю сильную ссылку на эту слабую ссылку в блоке, чтобы удерживатьк нему на время блока.

Проблема, с которой я столкнулся, заключается в том, что слабая ссылка (weakSelf) равна нулю при выполнении блока, но если я просто вызываю себя непосредственно в блоке, все работает.

- (void)fetchItemList:(NSArray *)itemList withHandler:(ItemFetchCompletion)completionHandler
{
    NSString *fetchString = [self fetchRequestUsingItemList:itemList];
    NSURL *fetchUrl = [NSURL URLWithString:fetchString];
    ASIHTTPRequest *itemListRequest = [ASIHTTPRequest requestWithURL:fetchUrl];
    __weak FetchManager *weakSelf = self;   
    __weak ASIHTTPRequest *itemListRequestWeakRef = itemListRequest;
    [itemListRequest setCompletionBlock:^{
        ASIHTTPRequest *itemListRequestStrongRef = itemListRequestWeakRef;
        ZAssert(weakSelf, @"weakSelf reference is nil.");
        FetchManager *strongSelf = weakSelf;        
        NSData *fetchedData = [itemListRequestStrongRef responseData];
        NSArray *fetchedItems = [strongSelf itemsFromFetchedData:fetchedData];
        completionHandler(fetchedItems);
    }];
    [itemListRequest startAsynchronous];
}

1 Ответ

4 голосов
/ 27 октября 2011

Вот, по сути, ваш код:

  1. Создание слабой переменной, weakSelf.
  2. Передача блока в функцию, которая ссылается на эту слабую переменную.

Эта точка, self, не сохраняется ни блоком, ни переменной weakSelf.Затем, когда блок выполняется, weakSelf помещается в переменную __strong, таким образом, сохраняя любое значение, которое было в weakSelf.К сожалению, если исходное значение weakSelf, а именно self уже было освобождено, weakSelf будет уже nil.

Компилятор может видеть, к каким внешним переменным обращается ваш блок, и затем добавляет любыенеобходимо сохранить, если эти переменные __strong.Компилятору все равно, что вы присваиваете переменную __weak внутренней переменной, которая оказывается __strong.Это сохранение произойдет , когда блок выполняется , а не при его создании.

Используя self непосредственно из блока, компилятор видит, что вы ссылаетесь на переменную, которая не __weak, и, следовательно, автоматически сохраняет эту переменную для жизненного цикла блока.В таких случаях я не вижу причин, по которым вы бы не ссылались непосредственно на себя в блоке, если вы не беспокоитесь о циклическом цикле сохранения.

...