在 @synchronized 代码块中进行提取和在锁定的 NSManagedObjectContext 中进行提取有啥不同

Posted

技术标签:

【中文标题】在 @synchronized 代码块中进行提取和在锁定的 NSManagedObjectContext 中进行提取有啥不同【英文标题】:Whats the different between doing a fetch in a @synchronized block of code and doing a fetch in a locked NSManagedObjectContext在 @synchronized 代码块中进行提取和在锁定的 NSManagedObjectContext 中进行提取有什么不同 【发布时间】:2013-01-24 10:32:13 【问题描述】:

我已经阅读了有关 @synchronized 和 NSManagedObjectContext 的 Apple 文档,但我根本看不清楚。

谁能解释一下这两段代码的区别:

这里有一个关键部分,我们在其中查询 NSManagedObjectConext

    @synchronized(self) 
        array = [mainContext executeFetchRequest:request error:&error];
        if (error != nil) 
            NSLog(@"Obj list fetch error: %@", error);
            exit(-1);
        
    

在这里,我们在锁定的 NSManagedObjectConext 中执行相同的查询

    [mainContext lock];
        array = [mainContext executeFetchRequest:request error:&error];
        if (error != nil) 
            NSLog(@"Obj list fetch error: %@", error);
            exit(-1);
        

    [mainContext unlock];

每个代码块的含义是什么?哪一个是正确的?

非常感谢,我有点困惑。

【问题讨论】:

第一段代码锁定运行代码的对象,第二段代码锁定托管对象上下文。如果在对象 A 中使用第一段代码,mainContext 仍然可以在任何其他对象 B 中使用,就像使用第二段代码一样,此时只能有一个线程访问 mainContext。 【参考方案1】:

如第一条评论所述,这是两种不同类型的锁。 一种是阻止其他线程访问您的类的整个实例,直到您完成为止。这意味着您不能调用此类的其他方法,或者更好的是,您发送到实例的消息被阻止。

另一个锁只是阻止访问您的 NSManagedObjectContext。

不过,Apple 表示没有必要同步上下文。相反,如果您有多个 NSManagedObjectContext 共享一个 NSPersistenceStoreCoordinator,则最好锁定协调器。

【讨论】:

以上是关于在 @synchronized 代码块中进行提取和在锁定的 NSManagedObjectContext 中进行提取有啥不同的主要内容,如果未能解决你的问题,请参考以下文章

[Java] synchronized在代码块中修饰.class与this的区别

在java中的synchronized方法或块中使用静态成员

synchronized(修饰方法和代码块)

Java中 wait和await notify和signal的区别

深入研究 Java Synchronize 和 Lock 的区别与用法

Webpack:从条目和子块中提取公共模块以分离公共块