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]

Reply via email to