objective-c - iOS6 和 ACAccount : Twitter type disappears?

标签 objective-c ios garbage-collection grand-central-dispatch

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

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

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

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

有点类似的事情发生了 here .

最佳答案

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

虽然我还没有看到这方面的正式文档,但是如果您 NSLog 一个帐户,您会看到它是一个 Core Data 对象,并且 Core Data 对象上缺乏线程安全性已得到很好的记录。

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

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

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

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

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

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

故事的寓意:将帐户本身放在一个线程中。如果你想对帐户的属性进行一些处理,那么将相关属性本身收集为基本的 Foundation 对象并将它们发布。

关于objective-c - iOS6 和 ACAccount : Twitter type disappears?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13771621/

相关文章:

iphone - 更改地址簿/联系人中的所有号码

ios - 此类不符合键登录的键值编码

ios - UIView.layer.presentationLayer 返回最终值(而不是当前值)

objective-c - UIButton 不可点击

ios - 如何使用 Stripe 和 Swift 获取卡片品牌

java - 标记-清除算法JAVA

iOS:URL 字符串中的 & 号问题

javascript - 当元标记存在时 HTML5 Canvas 不显示图像

ios - iOS 中不允许私有(private) API 调用(函数 "exc_server")

java - 垃圾收集如何识别孤立对象?