0

我已经测试了以下代码。

// 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(@"block test")),那么它的 dealloc 就会被调用。会有什么问题?

4

2 回答 2

2

It's circular reference, which will prevent the affected instance to be deallocated in the system of reference-count memory management.

According to the documentation

In a manually reference-counted environment, local variables used within the block are retained when the block is copied.

http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW3

john got retained when the block is copied to print, so it's like that john has retained itself via print variable. Even john will be released by the pool's draining, the reference count would never reach zero and dealloc would never get called.

于 2012-07-18T17:23:57.243 回答
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];
}
于 2012-07-18T17:33:02.950 回答