Coredata managedobjectContext和私有ivars的共享实例

时间:2012-02-20 19:19:28

标签: objective-c xcode core-data

到目前为止,我使用的是共享的Coredata实例。我在视图控制器中调用[[Storage instance] managedObjectContext]在视图控制器中传递的位置!

你说我可能是完全错的?请告诉我原因。

我注意到在大多数示例中,viewControllers在头文件中的@private中都有managedObjectContexts。为什么我们需要私人电话?

最后我们声明像

  NSManagedObjectContext *_managedObjectContext;
    @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

然后在viewController.m

@synthesize managedObjectContext = _managedObjectContext;

是什么意思“ _ ”managedObjectContext。为什么是下划线?

最后,这一切将如何影响iCloud?在一篇教程中,作者说,

  

ivars应该是私有的,所有代码都非常重要   总是通过访问器方法来确保这些   正确初始化。没有搞笑的 _ ,那么KVC可能会“帮助”我们   太多了。使用iCloud异步导入数据,还有更多   时间和多线程问题

没有搞笑的 _ ...请解释在这里发生的w ..

@interface LStorage : NSObject {

@private
    NSString *identifier;   
    NSManagedObjectContext *managedObjectContext;
    NSManagedObjectModel *managedObjectModel;
    NSPersistentStoreCoordinator *persistentStoreCoordinator;   
}

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;

+ (LStorage *) instance;

in  LStorage.m

+ (LStorage *) instance {
    @synchronized(self) {
        if (instance == nil) {
            instance = [[LStorage alloc] initWithIdentifier:kIdentifier];
        }
    }   
    return instance;
}
//identifier is just used to name the mom model filename.
- (id) initWithIdentifier:(NSString *)anIdentifier {
    self = [super init];

    if(self != nil) {
        identifier = anIdentifier;
    }

    return self;
}
- (NSManagedObjectContext *)managedObjectContext {

    if (managedObjectContext != nil) {
        return managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

    if (coordinator != nil) {
        // Make life easier by adopting the new NSManagedObjectContext concurrency API
        // the NSMainQueueConcurrencyType is good for interacting with views and controllers since
        // they are all bound to the main thread anyway

        if(IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0")){
        NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

        [moc performBlockAndWait:^{
            // even the post initialization needs to be done within the Block
            [moc setPersistentStoreCoordinator: coordinator];
            [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
        }];
        managedObjectContext = moc;
        }else{
            managedObjectContext = [[NSManagedObjectContext alloc] init];
            [managedObjectContext setPersistentStoreCoordinator:coordinator];
        }
    }

    return managedObjectContext;
}

1 个答案:

答案 0 :(得分:0)

您没有展示NSManagedObjectContext的初始化方式,但我假设您使用的是Apple提供的样板代码。如果是这种情况,你应该有一个评估员:

- (NSManagedObjectContext*)managedObjectContext
{
    if (_managedObjectContext != nil)
        return _managedObjectContext;
    // Code to initialise and return context here
}

请注意,managedObjectContext在此方法中已延迟加载。这意味着只有在第一次通过self.managedObjectContext[self managedObjectContext]访问方法时才会创建上下文(如果您可以从其他类访问该属性,则可以在外部创建)。

现在想象从未访问过此方法,因此您的_managedObjectContext ivar指向nil或内存垃圾。如果您尝试直接访问ivar,则会因为该内存块中没有存储NSManagedObjectContext而导致崩溃。

这也是通常在ivar名称的开头或结尾添加下划线(_)的原因,以避免您意外地直接访问ivar而不是通过其合成的getter。

如果ivar只是简单地命名为managedObjectContext,那么犯错误就更容易了,即你可能只写self.managedObjectContext而不是写managedObjectContext,而你突然直接访问了ivar。

基本上synthesize managedObjectContext = _managedObjectContext;的意思是 *合成一个名为managedObjectContext的getter(可能是setter)方法,并将其分配给名为_managedObjectContext的ivar。*