1、Part One
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
person.age = 10;
person.personBlock = ^{
NSLog(@"age is %d",person.age);
};
NSLog(@"----");
}
return 0;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
person.age = 10;
// __weak Person *weakPerson = person;
__weak typeof(person) weakPerson = person;
person.personBlock = ^{
NSLog(@"age is %d",weakPerson.age);
};
NSLog(@"----");
}
return 0;
}
内存图分析
2、Part 2
- 解决方案1
__weak 和__unsafe_unretained的区别:
__weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil(ARC环境下首选方案)
__unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变(这种不安全,不常用)
- 解决方案2(情况:必须调用block,才有可能调用置空方法)
使用__block
int main(int argc, const char * argv[]) {
@autoreleasepool {
__block Person *person = [[Person alloc] init];
person.age = 10;
person.personBlock = ^{
NSLog(@"age is %d",person.age);
person = nil;
};
person.personBlock();
NSLog(@"----");
}
return 0;
}
- 为什么使用__block,然后将person = nil 就可以解决循环引用?
1、先回顾下转换成c++代码(xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m)
typedef void (*Block)(void);
// 1. __block修饰的那部分:__block Person *person = [[Person alloc] init];
struct __Block_byref_person_0 {
void *__isa;
__Block_byref_person_0 *__forwarding;
int __flags;
int __size;
void (*__Block_byref_id_object_copy)(void*, void*);
void (*__Block_byref_id_object_dispose)(void*);
Person *__strong person; // 后面使用的person指针,都是这个指针
};
// 2.person.personBlock = ^{ ... }
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_person_0 *person; // by ref
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_person_0 *_person, int flags=0) : person(_person->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
- 图解,黄色标注的表示引用关系:
- 当执行personBlock 里面的 person = nil时候:
- 绿色的就释放了,就不会造成循环引用了
- 如果是在MRC情况下:
1.因为MRC不支持弱引用的情况,所以可以使用__unsafe_unretained
2.使用__block解决
因为__block不会对对象产生强引用