- 我们在写Block的时候,难免会出现循环引用,比如:
[self setDoSomething:^{
[self doOtherThing];
...
}];
- 那这个时候,我们需要破除循环引用,我们可以用__weak修饰符来修饰该类
1、直接使用该类的名称
__weak ViewController *weakSelf = self;
[self setDoSomething:^{
__strong ViewController *strongSelf = weakSelf;
[weakSelf doOtherThing];
}];
2、使用typeof 关键字,这种方法更好一点
__weak typeof(self) weakSelf = self;
[self setDoSomething:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf doOtherThing];
}];
- 为什么要在使用__weak修饰之后,在使用他的时候又再次进行了__strong修饰呢?
是为了防止weakSelf在不确定的时候释放掉了。 - 那在非ARC下是不能用__weak、__strong来修饰的,就需要用** __block**来打破retain cycle了。
-
__block在ARC和非ARC下的区别
在ARC中,__block会自动进行retain
在非ARC中,__block不会自动进行retain
要注意的一点就是用__block打破retain cycle的方法仅在非ARC下有效
但这样写起来也是很麻烦,所以我们就想到了宏定义
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
- 这样使用宏定义之后,我们就可以很方便的写了
@weakify(self)
[self setDoSomething:^{
@strongify(self)
[self doOtherThing];
}];