我已经测试了以下代码。
// Employee.h
@interface Employee : NSObject
@property(nonatomatic, copy) void (^print)(void);
@end
// Employee.m
@implementation Employee
@synthesize print = _print;
- (void)dealloc {
[_print release];
[super dealloc];
}
@end
// main.m
int main() {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
Employee* john = [[[Employee alloc] init] autorelease];
john.print = ^{
NSLog(@"block test %@", john);
};
[pool drain];
}
在这种情况下,不会调用变量“john”的dealloc。 但是,如果我不记录john变量(就像NSLog(@“块测试”)),那么它的dealloc被调用。 怎么会错?
答案 0 :(得分:2)
它是循环引用,它将阻止在引用计数内存管理系统中释放受影响的实例。
根据文件
当块被复制到在手动引用计数环境中,使用局部变量 复制块时,将保留块内的内容。
john
时, print
被保留,因此john
通过print
变量保留了自己。即使john
将被池的排放释放,引用计数也永远不会达到零,dealloc
永远不会被调用。
答案 1 :(得分:0)
正如tia所说,你在这里有一个保留周期。
以下是摆脱它的解决方案:
int main() {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
Employee* john = [[[Employee alloc] init] autorelease];
Employee* __weak weakjohn = john; // weak reference to john, to be used in the block.
john.print = ^{
NSLog(@"block test %@", weakjohn);
};
[pool drain];
}