创建工程:,先来一段简单的代码:
#import "ViewController.h"
@interface ViewController ()
// 1.声明block
@property (nonatomic,copy) void(^MyBlock)();
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 2.定义block
self.MyBlock = ^{
NSLog(@"%@",self.view);
};
// 3.执行block
self.MyBlock();
}
@end
这时Xcode会直接给予提示:
提示我们产生了循环引用:
self.Myblock --> 当前控制器对block产生强引用
self.view -->block对self(当前控制器)产生强引用
解决办法就是使用__weak修饰
#import "ViewController.h"
@interface ViewController ()
// 1.声明block
@property (nonatomic,copy) void(^MyBlock)();
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
__weak typeof(self) weakSelf = self;
// 2.定义block
self.MyBlock = ^{
NSLog(@"%@",weakSelf.view);
};
// 3.执行block
self.MyBlock();
}
@end
参考链接:http://www.jianshu.com/p/011bd4b8df7b
接下来对UI视图进行一些调整,进一步演示Block使用时的一些细节
1.嵌入导航控制器
2.点击导航控制器的根控制器的RightBarButtonItem,跳转到之前的ViewController控制器
3.在ViewController中重写Dealloc方法
4.在定义Block的内部,打印两次self.view,并在两次打印中间添加一个2s的延迟
改动代码后:
#import "ViewController.h"
@interface ViewController ()
// 1.声明block
@property (nonatomic,copy) void(^MyBlock)();
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 解决Block内部循环引用
__weak typeof(self) weakSelf = self;
// 2.定义block
self.MyBlock = ^{
/*
从Xcode 7.3开始,包括操作系统一旦升级后,就不需要强弱引用!
而在之前的版本中的写法为:
__strong typeof(weakSelf) strongSelf = weakSelf;
if(strongSelf){
NSLog(@"%@",strongSelf);
[NSThread sleepForTimeInterval:2];
NSLog(@"%@",strongSelf);
}
因为使用__weak修饰的对象,随时可能会被销毁,在之前版本中,如果不使用强引用,第二段打印代码结果就可能为nil
这也就是weak-strong dance的使用场景
*/
NSLog(@"%@",weakSelf.view);
[NSThread sleepForTimeInterval:2];
NSLog(@"%@",weakSelf.view);
};
// 3.异步执行block
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.MyBlock();
});
}
- (void)dealloc{
NSLog(@"%s",__func__);
}
@end
因为使用的是Xcode 7.3,所有成功打印出结果:
2016-08-12 12:04:30.573 Block扩展[3415:436303] >
2016-08-12 12:04:32.577 Block扩展[3415:436303] >
2016-08-12 12:04:32.577 Block扩展[3415:436260] -[ViewController dealloc]
weak-strong dance也是开发中需要注意的一个block使用的技巧,而更严谨一点的写法应该是:
__strong typeof(weakSelf) strongSelf = weakSelf;
if(strongSelf){
NSLog(@"%@",strongSelf);
[NSThread sleepForTimeInterval:2];
NSLog(@"%@",strongSelf);
}
但随着Xcode 7.3更新,已经为我们避免了这个问题,直接使用__weak就可以了