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
吗?或者有什么方法可以解除分配从未解除分配的上下文中获取的对象?
感谢帮助
- 不要为每个视图控制器创建
NSManagedObjectContext
。那没有任何价值。
- 考虑使用依赖注入,而不是单例。这是一个更好的设计,可以让您在添加测试或尝试重用视图控制器时省去麻烦。
数组未保留您的视图控制器,因此数组不会导致保留问题。但是,注释掉那行代码后,您的 _modules
变量是 nil
,这意味着针对该变量的其他 activity 将有一个 nil
响应。我建议通过您的视图控制器跟踪该变量,并找出导致保留循环的位置。它不在那行代码中。
此外,考虑使用 @property
而不是像这样的直接 ivar。它将允许编译器进行更多优化,并让 ARC 更好地完成工作。
最后,如果这是您正在使用的 table 视图,请考虑使用 NSFetchedResultsController
而不是您自己的数组。您将以更少的代码获得更卓越的性能。
当我在层次结构中返回时,我在解除分配我的控制器时遇到了问题。我发现问题出在从核心数据加载的对象上。当我注释掉带有 // *
的行时,控制器已成功解除分配,但在行中未打印 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
吗?或者有什么方法可以解除分配从未解除分配的上下文中获取的对象?
感谢帮助
- 不要为每个视图控制器创建
NSManagedObjectContext
。那没有任何价值。 - 考虑使用依赖注入,而不是单例。这是一个更好的设计,可以让您在添加测试或尝试重用视图控制器时省去麻烦。
数组未保留您的视图控制器,因此数组不会导致保留问题。但是,注释掉那行代码后,您的 _modules
变量是 nil
,这意味着针对该变量的其他 activity 将有一个 nil
响应。我建议通过您的视图控制器跟踪该变量,并找出导致保留循环的位置。它不在那行代码中。
此外,考虑使用 @property
而不是像这样的直接 ivar。它将允许编译器进行更多优化,并让 ARC 更好地完成工作。
最后,如果这是您正在使用的 table 视图,请考虑使用 NSFetchedResultsController
而不是您自己的数组。您将以更少的代码获得更卓越的性能。