循环引用问题

循环引用代码例子如下
#import <Foundation/Foundation.h>
typedef void(^CSBlock)(void);
@interface Person : NSObject
/** age*/
@property(nonatomic,assign)int age;
/** blokc*/
@property(nonatomic,copy) CSBlock block;
@end
@implementation Person
- (void)dealloc {
NSLog(@"%s",__func__);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
person.age = 100;
person.block = ^{
NSLog(@"age = %d",person.age);
};
}
NSLog(@"end");
return 0;
}
运行结果如下

解决循环引用问题 - ARC
-
用__weak、__unsafe_unretained解决
__weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil
__unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变

[图片上传中...(1653926-15dd8d8892a980c9.png-f61152-1542180021728-0)]
代码佐证
int main(int argc, const char * argv[]) {
@autoreleasepool {
// __weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil
// __unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变
Person *person = [[Person alloc] init];
person.age = 100;
// __weak typeof(person) weakPerson = person;
__unsafe_unretained typeof(person) weakPerson = person;
person.block = ^{
NSLog(@"age = %d",weakPerson.age);
};
}
NSLog(@"end");
return 0;
}
- 用__block解决(必须要调用block)

代码佐证
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 法三 __block
__block Person *person = [[Person alloc] init];
person.age = 10;
person.block = ^{
NSLog(@"age is %d", person.age);
person = nil;
};
person.block();
}
NSLog(@"end");
return 0;
}
运行结果

解决循环引用问题 - MRC
用__unsafe_unretained解决(MRC环境下不支持__weak)

用__block解决

代码例子佐证
int main(int argc, const char * argv[]) {
@autoreleasepool {
// MRC环境下
// MRC不支持__weak的
__block Person *person = [[Person alloc] init];
person.age = 10;
person.block = ^{
NSLog(@"age is %d", person.age);
};
[person release];
}
NSLog(@"end");
return 0;
}
运行结果如下

面试题 - Block
block的原理是怎样的?本质是什么?
封装了函数调用以及调用环境的OC对象
__block的作用是什么?有什么使用注意点?
block的属性修饰词为什么是copy?使用block有哪些使用注意?
block一旦没有进行copy操作,就不会在堆上
使用注意:循环引用问题
block在修改NSMutableArray,需不需要添加__block?
不需要
本文参考:
路飞_Luck (https://www.jianshu.com/p/07f7b96bb03f)
以及借鉴MJ的教程视频
非常感谢.
项目演示代码
iOS-block-cycle
网友评论