RetainCount OK to use in this instance?

前端 未结 2 596
-上瘾入骨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!

    0 讨论(0)
  • 2021-01-21 00:25

    Nope. You're relying on an abstracted implementation which publicly bears the sign "Keep Out" on its gate.

    Just manage your dependencies using your own memory and implementation. This might include an ivar and/or methods for completion/destruction phases.

    See also the documentation for release:

    release

    Decrements the receiver’s reference count. (required)

    - (oneway void)release

    Discussion

    The receiver is sent a dealloc message when its reference count reaches 0.

    You would only implement this method to define your own reference-counting scheme. Such implementations should not invoke the inherited method; that is, they should not include a release message to super.

    If you want to be sure your program behaves correctly across multiple releases, it's best to change it now.

    0 讨论(0)
提交回复
热议问题