NSManagedObjects 什么时候被释放?

When are NSManagedObjects deallocated?

当我在层次结构中返回时,我在解除分配我的控制器时遇到了问题。我发现问题出在从核心数据加载的对象上。当我注释掉带有 // * 的行时,控制器已成功解除分配,但在行中未打印 NSLog

我从控制器中提取代码:

@implementation ModulesListViewController {
  NSArray *_modules;
}

- (void)viewDidLoad {
  [super viewDidLoad];

  _modules = [[StorageManager manager] getModulesCDByUserEmail:userEmail]; // *
  ...
}

- (void)dealloc {
  NSLog(@"ModulesListViewController dealloc");
}

getModulesCDByUserEmail是从Core Data获取数据的方法,returnsNSArray。没有什么不寻常的。我想问题出在 NSManagedObjectContext.

- (NSManagedObjectContext *)managedObjectContext{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    _managedObjectContext.parentContext = [self writerManagedObjectContext];

    return _managedObjectContext;
}

我在单例中有它,它是全局可访问的,所以它没有被释放。这是个问题吗?如果我想正确解除分配,我应该为每个控制器创建自己的 NSManagedObjectContext 吗?这些上下文可以是 NSMainQueueConcurrencyType 吗?或者有什么方法可以解除分配从未解除分配的上下文中获取的对象?

感谢帮助

  1. 不要为每个视图控制器创建 NSManagedObjectContext。那没有任何价值。
  2. 考虑使用依赖注入,而不是单例。这是一个更好的设计,可以让您在添加测试或尝试重用视图控制器时省去麻烦。

数组未保留您的视图控制器,因此数组不会导致保留问题。但是,注释掉那行代码后,您的 _modules 变量是 nil,这意味着针对该变量的其他 activity 将有一个 nil 响应。我建议通过您的视图控制器跟踪该变量,并找出导致保留循环的位置。它不在那行代码中。

此外,考虑使用 @property 而不是像这样的直接 ivar。它将允许编译器进行更多优化,并让 ARC 更好地完成工作。

最后,如果这是您正在使用的 table 视图,请考虑使用 NSFetchedResultsController 而不是您自己的数组。您将以更少的代码获得更卓越的性能。