0

我尝试使用以下代码通过 Twitter 验证我的应用程序:pastebin

但是,如果我删除(无用的?)循环线 23ff

for (ACAccount *acc in arrayOfAccounts) {
    [acc accountType].identifier;
    //Otherwise the identifier get lost - god knows why -__-
}

acc.type 在 AccountHandler checkAccountOf:acc. 如果我保留循环,则类型设置正确。我很确定这与我在一个街区然后进入主队列的事实有关,但我想知道我是否做错了什么?这个循环看起来不像我应该做的事情。

这里发生了类似的事情。

4

1 回答 1

4

ACAccounts 不是线程安全的。您应该只在它们产生的线程上使用它们。为此,您可以将“线程”读作“队列”。

虽然我还没有看到正式的文档,但如果你NSLog是一个帐户,你会发现它是一个 Core Data 对象,并且 Core Data 对象缺乏线程安全性是有据可查的。

具体行为是 Core Data 对象可能是错误的。这意味着您持有的是对对象的引用,而不是实际对象。当您尝试访问属性时,该对象将被加载到内存中。

Core Data 在底层所做的是将事物缓存在内存中并返回错误,直到它知道确实需要一个对象。该缓存的有效协调是限制将对象协调到单个线程的核心数据对象的各个实例。

如果您在错误的线程上执行了应该将对象带入内存的操作(这是您identifier在此处访问时发生的情况),那么该行为是未定义的。你可能会得到一个nil结果,或者你可能会崩溃你的应用程序。

(除此之外:Core Data 像这样工作的原因是它存储了一个对象图,因此可能有 1000 个相互关联的对象,并且您可以像任何其他对象组一样遍历它。但是您通常不想支付成本与将它们中的每一个加载到内存中只是为了访问您将要使用的任何通常很小的信息子集相关联,因此它需要一种在延迟加载时提供普通 Objective-C 接口的方法)

通过确保对象在缓存中,因此在队列跳跃之前,您链接到的代码绕过了该问题。因此,“从商店获取”步骤发生在正确的队列上。然而,代码仍然是完全不安全的,因为根据 Core Data 关心应用的任何逻辑,对象可能会从内存中转换回故障。

作者显然认为他们在 Apple 方面发现了一些错误。他们没有,他们只是决定假设某些东西不是线程安全的,然后找到了一种依赖于在他们的测试中发生的未定义行为的方法。

故事的寓意:将帐户本身保持在一个线程上。如果您想对帐户的属性进行一些处理,则将相关属性本身收集为基础 Foundation 对象并将其发布。

于 2012-12-08T00:07:32.787 回答