为了防止循环引用,我们都会声明一个弱引用在block中使用,
那么weakSelf与strongSelf一起使用目的是什么呢?
首先先定义2个宏:
#define WeakSelf(type) __weak typeof(type) weak##type = type;
#define StrongSelf(type) __strong typeof(type) type = weak##type;
‘##’ 在宏的定义中可以起到拼接的作用
我们创建一个person并且在person.myBlock代码块中使用弱引用WeakSelf(person);
Person *person = [Person new];
person.name = @"张三";
WeakSelf(person);
person.myBlock = ^{
NSLog(@"person.name = %@",weakperson.name);
};
person.myBlock();
WeakSelf(person);与StrongSelf(person);一起使用
Person *person = [Person new];
person.name = @"张三";
WeakSelf(person);
person.myBlock = ^{
StrongSelf(person);
NSLog(@"person.name = %@",person.name);
};
person.myBlock();
这2种方式打印的结果都是person.name有值并且person也销毁了, 看起来完全一样:
但是我们再做一个测试:
仅仅使用WeakSelf(person);并且在myBlock中延迟输出person.name时就会出现问题
Person *person = [Person new];
person.name = @"张三";
WeakSelf(person);
person.myBlock = ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",weakperson.name);
});
};
person.myBlock();
可以看到, 虽然对象销毁了, 输出的值却是null。
再看看 WeakSelf(person);与StrongSelf(person);一起使用
Person *person = [Person new];
person.name = @"张三";
WeakSelf(person);
person.myBlock = ^{
StrongSelf(person);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",person.name);
});
};
person.myBlock();
打印结果:
可以看到输出的person.name有值,对象也销毁了。
通过上面的测试, 我们明显发现WeakSelf(person);与StrongSelf(person);一起使用时更安全一些, 不仅可以解决循环引用的问题,也不会导致对象提前释放出现野指针的情况,在block里能输出我们需要的值。