1 新建一个 TestObject的类,并在TestObject.m文件中重写dealloc方法,跟我一起做起来.
- (void)dealloc
{
NSLog(@"%@ dealloc",[self class]);
}
2.在控制器文件中我们设计一个这样的场景:
(1)先去初始化这个TestObject类得到一个obj对象,并在3s之后将这个对象obj设置为nil.
(2)先使用__weak修饰这个obj对象,并在block中每隔1s打印一下这个obj对象,看是否存在.
(3)再在block中通过__strong修饰这个obj对象,并在block中每隔1s打印一下这个obj对象,看是否存在.
结论:通过上面3个步骤的测试.我们得出结论:在使用__weak修饰block中持有的对象时,一旦这个对象在别的地方被销毁了,并且此时block还没有执行完毕,那么block内部的这个对象也就被销毁了,这种情况下程序一般都会crash.
但是:当我们在block里面对这个obj 对象再通过__strong修饰的时候,即便这个obj对象在其他的地方不小心被释放掉了(obj对象已经为nil),也就是说block外面的这个obj对象已经不存在了,此时如果block还没有执行完毕,那么block内部这个被引用的obj对象依然存在,直到block执行完毕的时候,obj才会被设置为nil!你没有看错,__strong就是这个拽的!!!下面我们看看代码.
#import "ViewController.h"
#import "TestObject.h"
@interface ViewController ()
/**
obj对象
*/
@property (nonatomic, strong)TestObject *obj;
@end
@implementation ViewController
/**
测试__weak \ __strong 在block中的作用
*/
- (void)viewDidLoad
{
[super viewDidLoad];
TestObject *obj = [[TestObject alloc] init];
self.obj = obj;
__weak __typeof(&*obj)weakObj = obj;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSInteger count = 0;
while (count < 6) {
count ++;
NSLog(@"<-----%@----->",weakObj);
sleep(1);
}
});
#pragma mark 3s后释放当前被引用的对象
[self deallocTargetObject];
}
/**
3s后释放当前被引用的对象
*/
- (void)deallocTargetObject
{
#pragma mark 3s后释放当前被引用的对象
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
self.obj = nil;
NSLog(@"<-deallocTargetObject----%@----->",self.obj);
});
}
@end
2017-01-06 10:52:19.839 __strong__block[61656:1831368] <-----<TestObject: 0x600000011660>----->
2017-01-06 10:52:20.841 __strong__block[61656:1831368] <-----<TestObject: 0x600000011660>----->
2017-01-06 10:52:21.847 __strong__block[61656:1831368] <-----<TestObject: 0x600000011660>----->
2017-01-06 10:52:22.839 __strong__block[61656:1831316] TestObject dealloc
2017-01-06 10:52:22.840 __strong__block[61656:1831316] <-deallocTargetObject----(null)----->
2017-01-06 10:52:22.850 __strong__block[61656:1831368] <-----(null)----->
2017-01-06 10:52:23.851 __strong__block[61656:1831368] <-----(null)----->
2017-01-06 10:52:24.855 __strong__block[61656:1831368] <-----(null)----->
通过打印的结果可以看到__weak修饰的obj对象,在3s后obj对象呗销毁了
再通过__strong修饰这个obj对象
- (void)viewDidLoad
{
[super viewDidLoad];
TestObject *obj = [[TestObject alloc] init];
self.obj = obj;
__weak __typeof(&*obj)weakObj = obj;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
#pragma mark 再通过__strong修饰这个obj对象
**__strong __typeof(&*obj)strongObj = weakObj;**
NSInteger count = 0;
while (count < 6) {
count ++;
NSLog(@"<-----%@----->",strongObj);
sleep(1);
}
});
#pragma mark 3s后释放当前被引用的对象
[self deallocTargetObject];
}
2017-01-06 10:29:59.391 __strong__block[61598:1812541] <-----<TestObject: 0x608000003a70>----->
2017-01-06 10:30:00.392 __strong__block[61598:1812541] <-----<TestObject: 0x608000003a70>----->
2017-01-06 10:30:01.397 __strong__block[61598:1812541] <-----<TestObject: 0x608000003a70>----->
2017-01-06 10:30:02.391 __strong__block[61598:1812483] <-deallocTargetObject----(null)----->
2017-01-06 10:30:02.401 __strong__block[61598:1812541] <-----<TestObject: 0x608000003a70>----->
2017-01-06 10:30:03.403 __strong__block[61598:1812541] <-----<TestObject: 0x608000003a70>----->
2017-01-06 10:30:04.407 __strong__block[61598:1812541] <-----<TestObject: 0x608000003a70>----->
2017-01-06 10:30:05.413 __strong__block[61598:1812541] TestObject dealloc
通过打印结果我们看到:当我们在block里面对这个obj 对象再通过__strong修饰的时候,即便这个obj对象在其他的地方不小心被释放掉了(obj对象已经为nil),也就是说block外面的这个obj对象已经不存在了,此时如果block还没有执行完毕,那么block内部这个被引用的obj对象依然存在,直到block执行完毕的时候,obj才会被设置为nil!你没有看错,__strong就是这个拽的!!