GC and Object Creation in Interface Builder - objective-c

In a project with garbage collection set to required: If I instantiate an object in Interface Builder and add it to the XIB/NIB, do I need to assign this object to some outlet to avoid it being garbage-collected, or is that taken care through some other means?

Top level objects need to be assigned to an outlet somewhere or attached to some variable using the top level objects array when instantiating the nib. Otherwise, they are useless to you anyway. A view which is contained within another view or window is in that views instance variables so it is safe.

I just built a small test project. With GC, the object created through Interface Builder gets collected soon afterwards. So the answer to the question is: yes.
I did a bit more testing:
With classical reference counting this does not happen. This is possibly what one would expect, but it is also probably a memory leak. Not sure here. (If not, and the NIB/XIB-contained objects get released when the file's owner is release, e.g., then this would constitute a significant difference in behavior between GC and classical RC.)
With ARC enabled, I did not find a way to tell. There is probably some function I could put a breakpoint on and wait for the specific object fly by.
Edit:
I reviewed the documentation, and it states it quite clearly. Missed that the first time around:
You typically need strong references to top-level objects to ensure that they are not deallocated; you don’t need strong references to objects lower down in the graph because they’re owned by their parents, and you should minimize the risk of creating strong reference cycles.
From: Resource Programming Guide, Managing the Lifetimes of Objects from Nib Files

Related

Controversy with ownership in Objective C

During the last time I'm trying to become aware of Objective-C memory management and once I asked myself the following question:
Sinceweak reference in Objective-C let us to avoid retain cycles why not to use them all the time?
An object only stays in memory while there is at least one strong (default) reference to it. If you only use weak references, the object is immediately deallocated.
Simply said, "weak" means: This object belongs to someone else, I'm only accessing it and I don't mind if it disappears.
Sinceweak reference in Objective-C let us to avoid retain cycles why not to use them all the time?
Because an object is deallocated as soon as there are no strong references to it.
More importantly, a strong reference is often wanted in order to prevent an object's deallocation. For example, a view controller is ultimately responsible for its view -- it wouldn't make much sense to have the controller's view suddenly just disappear. So UIViewController's view property is strong.
A retain cycle happens when two objects each have strong references to the other. Neither object can be deallocated as long as the other one keeps it's strong reference. This isn't really a problem if you're aware of the situation, because you can break the retain cycle by eliminating either of the references. However, it's easy to not be aware of the cycle, or to forget to deal with it, and then you've got two objects keeping each other in memory beyond their useful lifetime. Making one of those references weak eliminates the problem, but it also means that the referenced object may be deallocated and the reference may become nil at any point. In practice, that's usually not a problem.

Disadvantages of using weak variables even when not needed?

Seems Automatic Reference Counting (ARC) puts so much burden on the developer to keep track of references. Why couldn't you just make every variable weak and not have to worry about the strong retain cycles happening at all?
Im afraid you just dont understand ARC. ARC does the counting of references for you, depending on whether something is defined as strong or weak (in effect, strong increases the reference count, while weak does not). If a reference count becomes 0, it is removed from memory. So if everything was weak, properties would be removed from memory immediately, and you could not use them. You need a strong somewhere, in effect.
As a simple way to plan how to structure your strong / weak definitions, think of one particular class as the owner of a property, and give that one the strong. This means the property will stick around for that owner to use it. If another class also has a reference to that property, but does not require that the property always sticks around for it - make that weak. As long as the main owner class, say the View Controller, still exists - then so will the property. If both were set weak, then even though the property still appears, it will be empty, because at runtime, it was decided that no-one really needed it, and it was removed.
This is because you will need one strong reference as long as you need a reference to the object, as long as you need the referred object to survive in memory.
(You could go back to Objective-C where you can do all the works without ARC and do the memory management manually on your own. Apparently this could make you appreciate ARC.)
On the other hand you could ask the same question for strong references. The difference is that when you keep strong references only (no weak ones) then you don't have to think about weak or strong and it would work. (weak alone will most likely not work)
But then you would have to be 100% sure to null every strong reference to each object that you don't need anymore.
Side note:
When you add your object to a collection such as an array or a set (or as subview to a view) then these collection objects will keep strong references for you. In that case you don't have to care but to remove the object from that collection when the object can be discarded. This "trick" is only appropriate when you maintain these collections anyway - e.g. when it is about views that are part of the view hierarchy as long as they are required.
Under ARC object instance is alive as long as there is at least one strong reference to that object instance.
If you mark all variables as weak, there would be no strong references to object instance and nothing could keep it alive. It would be destroyed immediately upon creation.
If you are taking more than single reference to object instance you have to think about whether it should be marked as weak or strong (depending on particular code), there is no way around it.

In Cocoa under ARC can I get a list of objects that have references to another object (either programmatically or using Instruments)?

I am debugging the my Cocoa application and noticed using the Instruments.app allocation profile that the model object graph is not deallocating as I expect. Basically when I remove a root model object from the my NSDocument I was expecting the whole object graph for that object to be deallocated. That doesn't happen, which means that there is a strong reference to my root model object somewhere else in the application.
Is it possible to get a list of object which have a reference to a specific object in Cocoa either programmatically or using Instruments.app? If I could know where the strong reference is held this would help with debugging this problem.
I found this similar question, How to get the reference count of an NSObject?, but this simply says which how many references there are, not which objects hold the references.
Not in this way. The only information that is stored inside of a running process is the number of retains on an object (number of times "retain" has been called net the number of times "release" has been called). This is not the same as the number of references (number of "strong" pointers to the memory). Most memory locations do not have a side table of things that point to them in Cocoa.
In Instruments, you can turn on "record reference counts" and see everywhere the retain count is increased or decreased. See Instruments Allocations track alloc and dealloc of objects of user defined classes for a good explanation of how to do that. This won't tell you where you've made your mistake, but it will tell you where the retains are occurring.

In ObjC, how to describe balance between alloc/copy/retain and auto-/release, in terms of location

As is common knowledge, calls to alloc/copy/retain in Objective-C imply ownership and need to be balanced by a call to autorelease/release. How do you succinctly describe where this should happen? The word "succinct" is key. I can usually use intuition to guide me, but would like an explicit principle in case intuition fails and that can be use in discussions.
Properties simplify the matter (the rule is auto-/release happens in -dealloc and setters), but sometimes properties aren't a viable option (e.g. not everyone uses ObjC 2.0).
Sometimes the release should be in the same block. Other times the alloc/copy/retain happens in one method, which has a corresponding method where the release should occur (e.g. -init and -dealloc). It's this pairing of methods (where a method may be paired with itself) that seems to be key, but how can that be put into words? Also, what cases does the method-pairing notion miss? It doesn't seem to cover where you release properties, as setters are self-paired and -dealloc releases objects that aren't alloc/copy/retained in -init.
It feels like the object model is involved with my difficulty. There doesn't seem to be an element of the model that I can attach retain/release pairing to. Methods transform objects from valid state to valid state and send messages to other objects. The only natural pairings I see are object creation/destruction and method enter/exit.
Background:
This question was inspired by: "NSMutableDictionary does not get added into NSMutableArray". The asker of that question was releasing objects, but in such a way that might cause memory leaks. The alloc/copy/retain calls were generally balanced by releases, but in such a way that could cause memory leaks. The class was a delegate; some members were created in a delegate method (-parser:didStartElement:...) and released in -dealloc rather than in the corresponding (-parser:didEndElement:...) method. In this instance, properties seemed a good solution, but the question still remained of how to handle releasing when properties weren't involved.
Properties simplify the matter (the rule is auto-/release happens in -dealloc and setters), but sometimes properties aren't a viable option (e.g. not everyone uses ObjC 2.0).
This is a misunderstanding of the history of properties. While properties are new, accessors have always been a key part of ObjC. Properties just made it easier to write accessors. If you always use accessors, and you should, than most of these questions go away.
Before we had properties, we used Xcode's built-in accessor-writer (in the Script>Code menu), or with useful tools like Accessorizer to simplify the job (Accessorizer still simplifies property code). Or we just typed a lot of getters and setters by hand.
The question isn't where it should happen, it's when.
Release or autorelease an object if you have created it with +alloc, +new or -copy, or if you have sent it a -retain message.
Send -release when you don't care if the object continues to exist. Send -autorelease if you want to return it from the method you're in, but you don't care what happens to it after that.
I wouldn't say that dealloc is where you would call autorelease. And unless your object, whatever it may be, is linked to the life of a class, it doesn't necessarily need to be kept around for a retain in dealloc.
Here are my rules of thumb. You may do things in other ways.
I use release if the life of the
object I am using is limited to the
routine I am in now. Thus the object
gets created and released in that
routine. This is also the preferred
way if I am creating a lot of objects
in a routine, such as in a loop, and
I might want to release each object
before the next one is created in the
loop.
If the object I created in a method
needs to be passed back to the
caller, but I assume that the use of
the object will be transient and
limited to this run of the runloop, I
use autorelease. Here, I am trying to mimic many of Apple's convenience routines. (Want a quick string to use for a short period? Here you go, don't worry about owning it and it will get disposed appropriately.)
If I believe the object is to be kept
on a semi-permanent basis (like
longer than this run of the runloop),
I use create/new/copy in my method
name so the caller knows that they
are the owner of the object and will
have to release the object.
Any objects that are created by a
class and kept as a property with
retain (whether through the property
declaration or not), I release those
in dealloc (or in viewDidUnload as
appropriate).
Try not to let all this memory management overwhelm you. It is a lot easier than it sounds, and looking at a bunch of Apple's samples, and writing your own (and suffering bugs) will make you understand it better.

Self-owned objects in Objective-C Garbage Collection

I'm wondering what are the recommended ways to handle situations where, in memory managed code, object didn't belong to any particular owner, i.e. objects released themselves. One such example could be a subclass of NSWindowController, which configures, displays and manages input and output of a single window. The controller object displays a window and releases itself later at some point (usually when the window or sheet it manages is closed). AppKit provides couple examples as well: NSAnimation retains itself in startAnimation and releases itself when the animation is done. Another example is NSWindow, which can be configured to release itself when closed.
When implementing these "self-owned" objects myself, I see at least three different GC-safe patterns, but all of them have some drawbacks.
a). Using CFRetain/CFRelease.
Self-owned object calls CFRetain on self before it starts its operation (e.g. in the window controller example before the window is displayed). It then calls CFRelease() on self when it's done (e.g. in the window controller example after the window is closed).
Pros: User of the object doesn't have to worry about memory management.
Cons: A bit ugly, since requires use of memory management functions, although we're using GC in pure ObjC code. If CFRelease() isn't called, leak may be hard to locate.
b). Avoiding self-ownership idiom with static data structure.
Object adds itself into a data structure (e.g. a static mutable array) before it starts its operation and removes itself from there when it's done.
Pros: User of the object doesn't have to worry about memory management. No calls to memory management functions. Objects have explicit owner. Potential leaks are easy to locate.
Cons: Locking is needed if objects may be created from different threads. Extra data structure.
c). Avoiding self-ownership idiom by requiring the user of object to save a reference to the object (e.g. into an ivar).
Pros: No calls to memory management functions. Objects have explicit owner.
Cons: User of the object has to keep a reference even if it doesn't need the object anymore. Extra ivars.
What pattern would you use to handle these cases?
For a), the more idiomatic alternative to CFRetain(foo)/CFRelease(foo) is [[NSGarbageCollector defaultCollector] disableCollectorForPointer:foo]/[[NSGarbageCollector defaultCollector] enableCollectorForPointer:foo].
Apple's recommendation is (c), but I like the sound of (b). A static data structure allows you to hide the GC details from the API user while avoiding dipping into the CFRetain/CFRelease level. As you state, it also makes debugging and unit testing easier; if an object is still referenced by the static data structure after it's finished its task, you know there's a bug.