__autoreleasing for return value in ARC Objective-C - ios

According to Cocoa's "Create Rule" a method that returns a newly instantiated object must begin with either new, create, or copy if ownership is transferred to the caller.
Let's say I have a class that implements a factory method called (NSObject *)getCorrectObject.
This method will return a new instance of the correct subclass of the callee (determined by some internal state of the callee). Technically this method does not follow the "Create Rule" and could lead to memory leaks in non-ARC environments.
Would it be possible to instead use (NSObject *__autoreleasing)getCorrectObject to avoid using new or create in this case?
In non-ARC I would return an autoreleased object, but I'm not entirely sure if __autoreleasing works for anything other than In/Out parameters.

According to Cocoa's "Create Rule" a method that returns a newly instantiated object must begin with either new, create, or copy if ownership is transferred to the caller.
This isn't called the Create Rule (and isn't correct). The Create Rule is a Core Foundation rule related to the words Create and Copy. Cocoa has a different rule related to “alloc”, “new”, “copy”, or “mutableCopy”.
Let's say I have a class that implements a factory method called (NSObject *)getCorrectObject.
Then it would be incorrectly named. Starting a method with get indicates that it returns a value by reference. The correct signature would be:
+ (BOOL)getCorrectObject(NSObject**)result;
This method will return a new instance of the correct subclass of the callee (determined by some internal state of the callee). Technically this method does not follow the "Create Rule" and could lead to memory leaks in non-ARC environments.
That is not based on whether it is a new instance. It's based on whether it includes an unbalanced retain.
Methods that begin with “alloc”, “new”, “copy”, or “mutableCopy” should return an object with one unbalanced retain. Other methods should return an object that has an equal number of retain and autorelease attached to it.
If for some reason you have to violate these naming rules (and you really don't want to violate these rules), the correct way to indicate it to ARC is by using NS_RETURNS_RETAINED (see Foundation/NSObjCRuntime.h for all the macros). This only assists ARC in correctly fixing your memory management when dealing with mixed ARC/Retain code in cases where it is impossible to fix your incorrect naming. Pure ARC code doesn't need this; it'll balance out either way. Pure Retain code won't be helped by this. The caller has to do the right thing (and so has to just know that you did it wrong and compensate).
Note that as long as you're using ARC throughout the project (and you really, really should be), most of this won't matter a lot in practice. ARC will balance everything out for you pretty much no matter what you name things, since you're not in charge of adding the retains, releases, and autoreleases anyway.

Related

Manual reference counting and AutoRelease

In manual memory management on what scenarios you will go for Auto Release
I'd like to be well prepared as I am about to do a project using without ARC
You typically use autorelease when you need to return an object from a method, and relinquish ownership at the same time: upon returning the calling side (not the creating method) should own the object.
If you just relinquish ownership before returning the object (with release), it gets immediately deallocated and the calling side can not use it. If you don't call release, the object has a reference count of +1 from the called function (that instantiated it), which also has no further chance to release after the calling side has claimed ownership.
So, autorelease is like a "deferred release": the object gets sent one release method at a later time (but not before the function that is returning it returns).
Addendum:
The alternative approach is to return objects with an agreed-upon reference count of 1, and rely on the calling side to release it when done.
This is made explicit by adopting a preestablished naming pattern for those methods: In cocoa, they typically contain the words "alloc", "new", "copy" or "mutalbeCopy".
Source: Apple's documentation.

Does a TList<TProc>.Clear free all captured variables?

When I have a TList (so, a list of "reference to procedure"), and I Clear it, do all the captured variables used in the anonymous methods get freed, so no leaking occurs?
Ie. is reference counting in effect upon clearing the TList?
Delegate types are reference counted like interfaces (in fact they are implemented as interfaces). That means if they run out of scope the object behind the scenes (you might have seen that ArcRec$xxxx thing mentioned somewhere - that is the class name the compiler generates) gets destroyed. Captured variables are implemented as fields inside that class so they also run out of scope and are getting freed.
However you might pay attention to some circular referencing which might cause a memory leak with captured variables because of some important fact:
If you have multiple anonymous methods inside a single routine/method they all are implemented by one single class (that ArcRec$xxxx thing). So in this case the anonymous method with the longest lifetime might keep another one alive even if that already is out of scope.

ARC in iOS questions

~ Will ARC always release an object the line after the last strong pointer is removed? Or is it undetermined and at some unspecified point in the future it will be released? Similarly, assuming that you don't change anything with your program, will ARC always be the same each time you run and compile your program?
~ How do you deal with handing an object off to other classes? For example, suppose we are creating a Cake object in a Bakery class. This process would probably take a long time and involve many different methods, so it may be reasonable for us to put the cake in a strong property. Now suppose we want to hand this cake object off to a customer. The customer would also probably want to have a strong pointer to it. Is this ok? Having two classes with strong pointers to the same object? Or should we nil out the Bakery's pointer as soon as we hand off?
Your code should be structured so the answer to this doesn't matter - if you want to use an object, keep a pointer to it, don't rely on ARC side effects to keep it around :) And these side effects might change with different compilers.
Two strong pointers is absolutely fine. ARC will only release the object when both pointers are pointing to something else (or nothing!)
ARC will implement the proper retains and releases at compile time. It will not behave any different than if you put them in there yourself so it will always do the same compilation and to answer your question should always behave the same. But that said it does not mean that your object will always be released immediately after the pointer is removed. Because you never call dealloc directly in any form of objective C you are only telling it that there is no reference count and that it is safe to release. This usually means that it will be released right away though.
If you pass an object from one class to another and the receiving class has a strong property associated with it and the class that passes it off eventually nils its pointer it will still have a reference count of at least 1 and will be fine.
Ok, first this answer might helpt you also a little bit: ARC equivalent of autorelease?
Generally after the last strong variable is nilled, the object is released immediately. If you store it in a property, you can nil the property, assign it to something like __strong Foo *temp = self.bar; before you nil, and return that local __strong variable (although arc normally detects the return, and inferes the __strong byitself).
Some more details on that: Handling Pointer-to-Pointer Ownership Issues in ARC
DeanWombourne's answer is correct; but to add to (1).
In particular, the compiler may significantly re-order statements as a part of optimization. While method calls will always occur in the order written in code (because any method call may have side effects), any atomic expression may be re-ordered by the compiler as long as that re-order doesn't impact behavior. Same thing goes for local variable re-use, etc...
Thus, the ARC compiler will guarantee that a pointer is valid for as long as it is needed, no more. But there is no guarantee when the pointed to object might be released other than that it isn't going to happen beyond the scope of declaration. There is also no guarantee that object A is released before B simply because A is declared and last used before B.
IN other words, as long as you write your code without relying on side effects and race conditions, it should all just work.
Please keep you code proper as it has diffrent behaviour on diffrent complier.

How to ensure destruction of singleton in IOS 5 with ARC?

Say, I want to create a singleton which has some data inside. The data is dynamically allocated only once, as it expected on singleton.
But I would like to now under when and how this data can be is released. Should I establish special method which will destroy the singleton? To be more specific - when the method 'dealloc' for this singleton will be executed? who is responsible for that?
You can declare a method/function you call explicitly.
The simplest way is to have a static C++ class hold it, then release it in its destructor. If you have multiple singletons, then this approach does not extend very well because the destruction order is implementation defined.
Another alternative (and better design) would be to avoid the singleton approach, and just use it as a regular instance in another class which lives for the duration of your app (an app delegate is a commonly known example).
As to 'when', it depends on its dependencies and how it's used. It's also good to try to minimize external influence in destruction.
In general, a singleton is not different to a normal object. It is freed, if there is no (strong) reference to it anymore. Usually, you control that there is one object only by a static variable. This variable is created at compile time; therefore it can not be freed. But all the 'real' object stuff can.

Creating Objects on the fly in Objective-C

I'd like a critique of the following method I use to create objects:
In the interface file:
MyClass * _anObject;
...
#property (retain, nonatomic) MyClass * anObject;
In the implementation file:
#property anObject = _anObject
so far, so simple. Now let's override the default getter:
(MyClass *) anObject {
if(_anObject == nil) {
self.anObject = [[MyClass alloc] init];
[_anObject dowWhateverInitAction];
}
return _anObject;
}
EDIT:
My original question was about creating the object only (instead of the whole life-cycle), but I'm adding the following so that it doesn't through off anyone:
- (void) dealloc {
self.anObject = nil;
}
/EDIT
The main point of the exercise is that setter is used inside the getter. I've used it for all kind of objects (ViewController, myriad other types, etc.) The advantage I get is:
An object is created only when needed. It makes the app pretty fast
(for example, there are 6-7 views in an app, only one gets created in
the beginning).
I don't have to worry about creating an object before it's used... it happens automatically.
I don't have to worry about where the object will be needed the first time... I can just access the object as if it were already there and if it were not, it just gets created fresh.
Questions:
Does it happen to be an established pattern?
Do you see any drawbacks of doing this?
This pattern is quite commonly used as a lazy-loading technique, whereby the object is only created when first requested.
There could be a drawback to this approach if the object being created lazily takes a fair amount of computation to create, and is requested in a time-critical situation (in which case, it doesn't make sense to use this technique). However I would say that this is a reasonable enough thing to do should the object be quick to create.
The only thing wrong with your implementation (assuming you’re not using ARC yet) is that you’ve got a memory leak—using the setter means that your MyClass instance is getting over-retained. You should either release or autorelease _anObject after that initialization, or assign its value directly instead of calling the setter.
Aside from that, this is totally fine, and it’s a good pattern to follow when the MyClass is an object that isn’t necessarily needed right away and can be recreated easily: your response to memory warnings can include a self.anObject = nil to free up the instance’s memory.
It looks like a decent lazy initialization. Philosophically, one can argue that the drawback is that a getter has a side effect. But the side effect is not visible outside and it is kind of an established pattern.
Lazy instantiation is an established pattern, and it is used by Apple in their (terrible) Core Data templates.
The main drawback is that it is overly complex and often unnecessary. I've lost count of the number of times I've seen this where it would make more sense to simply instantiate the objects when the parent object is initialised.
If a simple solution is just as good, go with the simpler solution. Is there are particular reason why you can't instantiate these objects when the parent object is initialised? Perhaps the child objects take up a lot of memory and are only rarely accessed? Does it take a significant amount of time to create the object and you are initialising your parent object in a time-sensitive section of your application? Then feel free to use lazy instantiation. But for the most part, you should prefer the simpler approach.
It's also not thread-safe.
Regarding your advantages:
An object is created only when needed. It makes the app pretty fast (for example, there are 6-7 views in an app, only one gets created in the beginning).
Are you referring to views or view controllers? Your statement doesn't really make sense with views. I don't normally find myself needing to store view controllers in instance variables/properties at all, I instantiate them when I need to switch to them and push them onto the navigation stack, then pop them off when I'm done.
Have you tried your app without using this pattern? Conjecture about performance is often wrong.
I don't have to worry about creating an object before it's used... it happens automatically.
No, now you have to worry about writing a special getter instead. This is more complex and prone to mistakes than simple instantiation. It also makes your application logic and performance more difficult to understand and reason about.
I don't have to worry about where the object will be needed the first time... I can just access the object as if it were already there and if it were not, it just gets created fresh.
You don't have to worry about that when you instantiate it during your parent object's initialisation.
Yes this is an established pattern. I often use lazy instantiation like this as an alternative to cluttering up -init or -viewDidLoad with a bunch of setup code. I would assign the value to the instance variable instead of using the synthesized setter in the event that this object ends up being created as a result of something happening in -init.

Resources