关于循环引用的问题

在微博上看到 @我就叫Sunny怎么了 提出了一个问题:看下面的一段代码,想一想是否会造成循环引用?

__weak typeof(self) weakSelf = self
self.foo.block = ^ {
    __strong typeof(self) strongSelf = weakSelf;
    NSlog(@"%@",strongSelf);
};

首先要观察到问题不在于 weak_strong 的模式,而是 block 中出现了 typeof(self), 而不是 typeof(weakSelf), 那究竟 block 会不会 capture 这个 typeof 中的 self 呢?
答案是不会引起循环引用问题,因为 typeof 操作符的计算发生在编译时,而不是运行时,所以不会被 block capture。

对于上面的答案,我不敢肯定是对或者错。从 AFNetworking 对于 block 中用到 self 的写法来看,在 Block 内部最好还是使用 __strong typeof(weakSelf) strongSelf = weakSelf 来避免 weakSelf 在 block 使用过程中被释放掉了。

__weak __typeof(self)weakSelf = self;
AFHTTPRequestOperation *backgroundImageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
backgroundImageRequestOperation.responseSerializer = self.imageResponseSerializer;
[backgroundImageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;
    if ([[urlRequest URL] isEqual:[operation.request URL]]) {
        if (success) {
            success(operation.request, operation.response, responseObject);
        } else if (responseObject) {
            [strongSelf setBackgroundImage:responseObject forState:state];
        }
    }
    [[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    if ([[urlRequest URL] isEqual:[operation.request URL]]) {
        if (failure) {
            failure(error);
        }
    }
}];

虽然说是 block 里面要使用 weakSelf 来避免循环引用,但对于苹果自带的一些 api 来说,block 里面用到 self 却不用担心循环引用的问题。当然,block 内部也不会使用到 weakSelf
例如这些:

dispatch_async(dispatch_get_main_queue(), ^{
        //[self something]
    });

另外,在 stackoverflow 上也找了一些关于循环引用的一些问题,可做参考,强烈建议看一下。
参考:Always pass weak reference of self into block in ARC?