在ARC下的块中消失了对self的引用

时间:2011-10-26 14:58:28

标签: objective-c-blocks automatic-ref-counting

我无法弄清楚为什么__weak引用self会在下一个块中消失。遵循Jiva的建议在这里找到 http://blog.random-ideas.net/?p=160我在完成块之外对self进行__weak引用,然后对块内的弱引用进行强引用,以便在块的持续时间内保持它。

我遇到的问题是,当块执行时弱引用(weakSelf)为零,但如果我只是在块中直接调用self,则一切正常。

- (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 个答案:

答案 0 :(得分:4)

这基本上是您的代码正在做的事情:

  1. 制作弱变量weakSelf
  2. 将块传递给引用该弱变量的函数。
  3. 此时,self不会被块保留,也不会保留weakSelf变量。然后,当块运行时,weakSelf被放入__strong变量,从而保留weakSelf中的任何值。很遗憾,如果weakSelf的原始值self已经取消分配,则weakSelf已经nil

    编译器可以查看块访问的外部变量,然后在这些变量为__strong时添加任何必要的保留。编译器并不关心您将__weak变量分配给恰好为__strong的内部变量。当块运行时,此保留将发生,而不是在创建时。

    通过直接从块中使用self,编译器会发现您引用的变量不是__weak,因此会自动将该变量保留在块的生命周期中。在这种情况下,除非你担心循环保留周期,否则我认为没有理由不直接在块中引用self。