我有一个涉及 ARC、NSNotificationCenter 和一个块的奇怪案例。以下是代码的简化示例。从测试来看,内存管理似乎 didSaveObserver是按预期执行的,即它没有创建保留周期并且之前没有被nil编辑过removeObserver:。
但是,我对 ARC 的理解让我认为这只是一个侥幸/怪癖,而 ARCnil didSaveObserver之前可能会removeObserver:。看到 asdidSaveObserver永远不会保留(唯一的分配是对weak变量),那么 ARC 可以/(应该?)立即解除分配它。
我是否正确理解了 ARC 规则?如果是这样,那么我如何确保didSaveObserver保留它以便它可以不被观察但不会创建保留周期?
self.willSaveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextWillSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
id preSaveState = ...; //Store some interesting state about a Core Data object (the details aren't significant to this question).
__weak __block id didSaveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
//Unobserve the did save block. This is the tricky bit! didSaveObserver must be __weak to avoid a retain cycle, but doing so also means that the block may be dealloced before it can be unobsered.
[[NSNotificationCenter defaultCenter] removeObserver:didSaveObserver];
id postSaveState = ...;
//Perform work that uses pre & post save states.
}];
}];
更多细节:
如果__weak未添加(因此默认为__strong) Instruments 报告存在保留周期。