RetainCount OK to use in this instance?

前端 未结 2 597
-上瘾入骨i
-上瘾入骨i 2021-01-20 23:44

RetainCount == BAD

retainCount is taboo, unreliable, unpredictable, and in general shouldn\'t be used. I don\'t use it anywhere in my code, but I have se

2条回答
  •  感情败类
    2021-01-21 00:03

    retainCount is taboo, unreliable, unpredictable, and in general shouldn't be used.

    You can rely on the value of retainCount IFF your objects don't pass through any code that's opaque to you, such as any Cocoa framework. In practice, this is almost impossible to achieve, thus the warning. The internals of Cocoa may be passing your object around, retaining, releasing, and putting it into autorelease pools many times and for many reasons, and you can't rely on its absolute value at any given point.

    The catch is that the thread increases the retain count of the owner, in my case the class that instantiated it.

    That's a retain cycle. The answer here is to find a way to break that cycle, not to subvert the reference counting mechanism. There must be some point before deallocation when either your thread or the owning object knows that the work the thread is performing is done (or needs to stop prematurely).

    It sounds like the owning object is the interface for client code to the work the thread is doing. This owning object needs a "shutdown now" method that needs to be called (and documented as "must be called") before its owner releases it. In that shutdown method, you can break the cycle by releasing the thread.

    I'm not exactly sure what's going on that the thread is retaining its creator (the cycle is a pretty clear indication that something is wrong with your ownership model) -- I'd guess you're using NSThread and initWithTarget:..., with the target being the creating/owning object. This is a bit of a mixup of the standard MVC pattern -- the owner of the thread is a "controller", the thread itself (and the code it runs) more of a "model".

    The controller should not contain the thread's code, in other words. I'd recommend that you factor out the thread's code into another object to use as the target. Then the controller object owns both the thread itself and the "work" target object, with neither of them owning the controller. Voilà, no cycle!

提交回复
热议问题