【发布时间】:2014-06-07 04:53:40
【问题描述】:
我对 ARC 下的块的生命周期感到困惑。我已经编写了一个单元测试来演示什么让我感到困惑。
- (void)testBlock {
NSObject *testObject = [[NSObject alloc] init];
CompletionBlock testBlock = ^{ NSLog(@"%@", testObject); };
XCTAssertNotNil(testObject, @"testObject should not be nil");
__weak NSObject *weakTestObject = testObject;
@autoreleasepool {
testObject = nil;
}
XCTAssertNotNil(weakTestObject, @"testObject should be retained by testBlock");
@autoreleasepool {
testBlock = nil;
}
//THIS IS THE FAILING TEST CASE
XCTAssertNil(weakTestObject, @"testObject should have been released when testBlock was released");
}
我猜测这种行为与块在堆栈/堆中的存储方式有关。
更新!
将块设置为 nil 不会像我预期的那样释放块,因为它在堆栈上并且在超出范围之前不会被释放。强制块超出范围修复了我的测试。下面更新了代码。
- (void)testBlock {
NSObject *testObject = [[NSObject alloc] init];
__weak NSObject *weakTestObject = testObject;
@autoreleasepool {
CompletionBlock testBlock = ^{ NSLog(@"%@", testObject); };
XCTAssertNotNil(testBlock, @"testBlock should not be nil");
XCTAssertNotNil(testObject, @"testObject should not be nil");
testObject = nil;
XCTAssertNotNil(weakTestObject, @"testObject should be retained by testBlock");
//testBlock goes out of scope here
}
XCTAssertNil(weakTestObject, @"testObject should have been released when testBlock was released");
}
【问题讨论】:
标签: objective-c objective-c-blocks