在微博上看到 @我就叫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?