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

eos_et 发布于 2019-11-10 deadlock 最后更新 2019-11-10 12:10 75 浏览

内容太长未翻译

已邀请:

beos

赞同来自:

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

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

taut

赞同来自:

-release超载是一个很好的迹象,表明你遇到了麻烦.... IMO的真正问题在于您在步骤2中采用长期锁定以迭代列表。由于可能发生的所有其他步骤(其中一些可重入),很难保持这种锁原子。 解决此问题的方法是放松对数据的保留。首先,每个客户端都应该有一个唯一的标识符(如果没有更方便的话,它的内存位置就可以了)。创建identifier-> client字典。现在,在第二步中,锁定字典并拍摄标识符的快照。然后立即解锁字典。当呼叫者希望自己移除时,锁定字典,删除它们,然后解锁。 现在,如果有人在你提出问题的过程中消失了,那没关系。您将获取您的标识符,查看字典,并发现没有这样的对象。扔标识符(它只是一个字符串)并移动到下一个标识符。如果某人出现在迭代的中间,你不会问他们那个回合,但希望在第一次迭代中这是可以接受的(当然,如果没有,那么就有解决方案)。 编辑:这个问题的一个更简单的解决方案可能就是让BossOfEverthing -retain在它开始向他们提问之前让所有客户端完成,然后在完成后再使用-release。这将确保在问题提出期间没有一个dealloc。如果重要的是他们都真正回答了这个问题,这是一个很好的解决方案。