SDwebImage 中有一段源码:
- #if SD_UIKIT
- Class UIApplicationClass = NSClassFromString(@"UIApplication");
- BOOL hasApplication = UIApplicationClass && [UIApplicationClass respondsToSelector:@selector(sharedApplication)];
- if (hasApplication && [self shouldContinueWhenAppEntersBackground]) {
- __weak __typeof__ (self) wself = self;
- UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)];
- self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{
- __strong __typeof (wself) sself = wself;
- if (sself) {
- [sself cancel];
- [app endBackgroundTask:sself.backgroundTaskId];
- sself.backgroundTaskId = UIBackgroundTaskInvalid;
- }
- }];
- }
- #endif
- // AFNetworking 中 AFNetworkReachabilityManager.m 的一段代码
- __weak __typeof(self)weakSelf = self;
- AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
- __strong __typeof(weakSelf)strongSelf = weakSelf;
- strongSelf.networkReachabilityStatus = status;
- if (strongSelf.networkReachabilityStatusBlock) {
- strongSelf.networkReachabilityStatusBlock(status);
- }
- };
我们用的比较多的 解决循环引用的问题, 在 block 中 用到对象内部的属性, 实例变量的时候要用 weakSelf 访问, 但是为什么 block 内部又用到 strongSelf 呢?
大部分情况下, 只在 block 中使用 weakSelf 是没有问题的, 通常情况下我们只在 block 中做一个任务, 执行完之后回调, 但是如果我们要在 block 中做多个任务, 而且第一个任务执行完有可能调用者会释放了 self,self = nil, 那么 第二个任务执行时就报错, nil 可以接受任何消息, 但是不能发送消息哦??.
- //clang 给出的实例代码:
- __weak __typeof__(self) weakSelf = self;
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- [weakSelf doSomething];
- });
- //clang 的文档表示, 在 doSomething 内, weakSelf 不会被释放. 但, 下面的情况除外:
- __weak __typeof__(self) weakSelf = self;
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- [weakSelf doSomething];
- [weakSelf doOtherThing];
- });
在 doSomething 中, weakSelf 不会变成 nil, 不过在 doSomething 执行完成, 调用第二个方法 doOtherThing 的时候, weakSelf 有可能被释放,
- // 于是, strongSelf 就派上用场了:
- __weak __typeof__(self) weakSelf = self;
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- __strong __typeof(self) strongSelf = weakSelf;
- [strongSelf doSomething];
- [strongSelf doOtherThing];
- });
__strong 确保 strongSelf 在 block 中不会被释放.
所以就能理解 SDWebImage 中的那段代码, block 在实现的过程中会对 wself 进行一次强引用, 是为了防止在 block 还未执行完毕, wself 在其他线程中被释放, 使得 wself 为 nil.
https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/
来源: http://www.bubuko.com/infodetail-2550733.html