On Apr 25, 2017, at 16:18 , Jonathan Schleifer <[email protected]>
wrote:
>
> nonatomic is even unsafe in single-threaded code.
It is not (and never has been, AFAIK) a requirement that a getter return an
autoreleased value. It’s been a popular getter pattern, but there’s never been
an API contract. The only requirement is that the getter should ensure that the
returned value stays alive until the return is complete. After that, it’s the
responsibility of the caller to keep the object alive by retaining it if
necessary.
If you look at the documentation:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html
<https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html>
(“Use Accessor Methods to Make Memory Management Easier”) the example getter
has no retain/autorelease, and the text says:
> In the “get” accessor, you just return the [already-retained] synthesized
> instance variable, so there is no need for retain or release
and further down (“Avoid Causing Deallocation of Objects You’re Using”) it
clarifies the cases where the caller might need to memory-manage the returned
value.
The scenario where the retain/autorelease pattern *is* documented is where
there is no lifetime-preserving reference that lasts through the return, such
as in:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
<https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>
under (“Use autorelease to Send a Deferred release”).
But put that aside. The *real* truth is that MRR memory management has always
been broken, because we relied on a heuristic for ensuring that memory
deallocations don’t happen at inopportune times. In particular, even if a
getter returns an autoreleased reference, you must still retain the returned
value *if there’s a possibility that the autorelease pool will be drained*
while the returned value is still in use though un-re-retained. Luckily, this
was an uncommon scenario.
You also said:
> If you use Key Value Coding, this does not work: valueForKey: is assumed to
> return retained and autoreleased
This is not assumed — it is not a KVC requirement (AFAICT). Because it returns
a net +0 retained result, it may be like the string in the second link above
(which would need to be retained and autoreleased, because that used to be the
only mechanism for ensuring the reference stayed alive during the return), or
it may be like the getter in the first link above (which is just the value of a
strong instance variable, which therefore stays alive during the return).
The truth is that MRR has always been “fragile”, at best. We used to follow
various patterns for avoiding memory management bugs, which worked most of the
time, and we painfully debugged the bugs in the other cases. Now, the real
solution is ARC. Except when minimally maintaining legacy code, there’s no good
reason for anyone to use MRR over ARC any more.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Objc-language mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/objc-language/archive%40mail-archive.com
This email sent to [email protected]