谁能告诉我为什么当test参数和testMember变量指向同一地址时,以下代码会导致不同的结果
@interface TestClass : NSObject
@property (nonatomic, copy) void (^testBlock)(TestClass *test);
@end
@implementation TestClass
- (void)viewDidLoad {
[super viewDidLoad];
self.testBlock(self);
}
@end
@implementation OtherClass
- (void)viewDidLoad {
[super viewDidLoad];
TestClass *testMember = [[TestClass alloc] init];
// Case 1
testMember.testBlock = ^(TestClass *test) {
NSLog(@"%@",test); // This does not create circular references
};
// Case 2
testMember.testBlock = ^(TestClass *test) {
NSLog(@"%@",testMember); // This creates circular references
};
}
@end
答案 0 :(得分:0)
对于情况1,test
变量只是一个局部函数参数,该块没有从外部保留任何其他变量。
对于情况2,testMember
对象在定义块时来自块外部,该块保留其引用计数。由于testBlock
被定义为类TestClass
的属性,因此testMember
拥有testBlock
。因此,testMember
和testBlock
相互保留,这就是循环引用。
要解决案例2的循环保留问题,请使用以下方法:
__weak TestObject *weakMember = testMember;
testMember.testBlock = ^(TestClass *test) {
__strong TestObject *strongMember = weakMember;
NSLog(@"%@", strongMember);
};
因为weakMember
变量不会增加实际testMember
对象的引用计数,所以testBlock
也不会增加。当开始执行testBlock
时,strongMember
尝试保留weakMember
对象(该对象可能会获得nil值取决于您的逻辑设计),并在完成该块时减少引用计数。 / p>