Objective-C / Cocoa线程和消息传递难题

时间:2009-11-28 04:10:39

标签: objective-c multithreading delegates deadlock messaging

2 个答案:

答案 0 :(得分:1)

-release的超载是一个很好的迹象,表明你遇到了麻烦......

真正的问题IMO是你在第2步中进行长期锁定以迭代列表。由于可能发生的所有其他步骤(其中一些可重入),很难保持这种锁定原子。

解决此问题的方法是放松对数据的保留。首先,每个客户端都应该有一个唯一的标识符(如果没有更方便的话,它的内存位置就可以了)。创建标识符 - >客户端的字典。现在,在第二步中,锁定字典并拍摄标识符的快照。然后立即解锁字典。当呼叫者希望自行删除时,请锁定字典,将其删除,然后解锁。

现在,如果有人在你回答问题时消失了,那没关系。你将获取你的标识符,查看字典,发现没有这样的对象。扔标识符(它只是一个字符串)并移动到下一个。如果有人在迭代过程中出现,你就不会问他们那个回合,但希望在第一次迭代中这是可以接受的(当然,如果没有,那么就有解决方案)。

编辑:对所有这些问题更简单的解决方案可能就是让BossOfEverthing -retain在所有客户开始问他们问题之前让它们完成,然后-release完成它们。这将确保在提出问题时没有一个人被解除谴责。如果重要的是他们都真正回答了这个问题,那么这是一个很好的解决方案。

答案 1 :(得分:1)

当您要迭代客户端数组时,我会这样做:

  1. 获取锁
  2. 制作客户端数组的浅表副本
  3. 解除锁定
  4. 迭代数组副本
  5. 通过复制数组,会在每个客户端对象上放置一个retain,这将阻止它们在迭代期间被释放。此外,在迭代开始之前释放锁定,这将避免死锁。此外,它允许客户在迭代期间调用removeMeFromYourClientList:,这可能有用也可能没有用。