【问题标题】:Shared instance of Coredata managedobjectContext and private ivarsCoredata managedobjectContext 和私有 ivars 的共享实例
【发布时间】:2012-02-21 08:52:42
【问题描述】:

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

你说我可能是大错特错?请告诉我为什么。

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

最后我们声明一下

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

然后在 viewController.m 中

@synthesize managedObjectContext = _managedObjectContext;

_”managedObjectContext有什么意义。为什么下划线?

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

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

没有有趣的_ ...请解释这里发生的事情..

@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;
}

【问题讨论】:

    标签: objective-c xcode core-data


    【解决方案1】:

    您没有显示 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。*

    【讨论】:

    • 您的初始化程序很好,我对您在该类中的 managedObjectContext 方法更感兴趣。
    • 刚刚添加.. 但我不符合 _managed 下划线!既然我明白了,我应该这样做!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多