【发布时间】:2011-04-01 12:39:59
【问题描述】:
我的一个实体托管对象需要设置一个仅运行时的树状结构,其中节点是NSObject 的子类(它们不是托管对象)。
我在两个地方设置了该结构(并因此分配了一堆节点):
- 创建新的此类托管对象时:一切正常。
- 在回读现有托管对象时,在其
awakeFromFetch方法中。
这就是我的问题所在:对Node *newNode = [Node alloc]; 的调用永远不会返回。我可以使用调试器中断,代码卡在semaphore_wait_signal_trap。这是完整的调用堆栈:
#0 0x937ac0e2 in semaphore_wait_signal_trap ()
#1 0x937b1be6 in pthread_mutex_lock ()
#2 0x01881c73 in _class_initialize ()
#3 0x0188973f in prepareForMethodLookup ()
#4 0x01880069 in lookUpMethod ()
#5 0x018801d6 in _class_lookupMethodAndLoadCache ()
#6 0x018930e3 in objc_msgSend ()
#7 0x000957d8 in -[MyEntity awakeFromFetch] at MyEntity:114
看来我的 Node 类无法初始化。事实上,这是本次会议中第一次使用 Node 类。为了检查这一点,我在应用程序启动时插入了单个 Node 的虚假分配。那调用成功了,现在上面的问题就消失了。
但是,我不满意,有两个原因:
1- 我仍然不明白为什么在awakeFromFetch 中第一次分配Node 会失败。如果我不明白为什么会发生错误以及为什么修复是实际修复,我不会认为它已修复。
2- 应用程序现在在第一次使用 another 类时稍晚崩溃,这次不是在任何awakeFromFetch 中。
很明显我的问题与awakeFromFetch 和Core Data 无关。不知何故,我的 Objective-C 运行时行为异常,我不知道为什么。
简单的问题:什么会导致_class_initialize 导致 p 线程死锁?
确实,在谷歌上搜索 semaphore_wait_signal_trap 会产生很多命中,都与 pthread 相关,很少与 iOS/Objective-C/Cocoa 相关。
请注意,我在这里根本不使用线程。
我很困惑。知道如何调试吗?
编辑:永远不会返回的源代码行是:
Node *newNode = [[Node alloc] init];
为了弄清楚发生了什么,我把它分成了两部分:
Node *newNode = [Node alloc];
newNode = [newNode init];
问题出现在这两行的第一行。
【问题讨论】:
-
不确定我是否理解这个问题,但我注意到 2 件事 [1] 节点分配后没有初始化(因此未设置对象调用堆栈)和 [2] 堆栈看起来像未找到 AwakeFromFetch 方法。
-
init在alloc之后。因为alloc永远不会返回*,所以init还没有[尚未] 被调用。awakeFromFetch在调用堆栈中:它当前正在执行。 * 实际上,alloc甚至从未被调用过,因为在一个类可以被使用(例如分配)之前,它必须在_class_initialize例程中被初始化。这是一个死锁,甚至在 `alloca 被调用之前。
标签: objective-c ios deadlock semaphore