NSMutableArray subclass not calling subclass's initWithCoder when unarchiving - iphone

I have a subclass of NSMutableArray that contains various configuration information along with it's normal array data.
When I archive the subclass, the subclass's encodeWithCoder method is called, but when I unarchive it, the initWithCoder is never called. However, it appears that NSMutableArray's initWithCoder method is called because it returns an NSMutableArray, and not an instance of my subclass.
Any ideas about what's going on?

Related

Objective C: Subclassing, overriding dealloc

I am creating a subclass of a custom UITableViewCell. The superclass has some properties that it is releasing in the dealloc method. I have added one additional property in my subclass, so I made sure to override the dealloc method and release my new property.
My question is, since I overrode the dealloc method, will the properties that were released in super class dealloc method not get released (I AM calling [super dealloc])? Do I need to specifically release those in MY dealloc method?
If you are calling [super dealloc], then the superclass implementation of -dealloc will still be run. The superclass should be responsible for releasing its own properties. So no, you don't need to release the superclass properties. In fact, doing so will likely cause your application to crash.
If you are calling [super dealloc], you are fine. That method won't know if it was called by a subclass or directly by the runtime, and it will do its usual work and take care of its own properties as always.
Important: Call [super dealloc] last in your -dealloc method, after you've your own ivars and done anything else you need to do in -dealloc. There won't be anything left of your object when that method returns.

What initializer exactly is called when a property is linked to a IBOutlet?

When you link an object to an IBOutlet, what method of the class does it use to create the instance? Alloc/init?
"during the instantiation process, each object in the archive is unarchived and then initialized with the method befitting its type. Objects that conform to the NSCoding protocol (including all subclasses of UIView and UIViewController) are initialized using their initWithCoder: method. All objects that do not conform to the NSCoding protocol are initialized using their init method. After all objects have been instantiated and initialized, the nib-loading code reestablishes the outlet and action connections for all of those objects. It then calls the awakeFromNib method of the objects. For more detailed information about the steps followed during the nib-loading process, see Nib Files and Cocoa in Resource Programming Guide."
http://developer.apple.com/library/ios/documentation/uikit/reference/NSObject_UIKitAdditions/Introduction/Introduction.html#//apple_ref/occ/instm/NSObject/awakeFromNib
Depends on the object parent class, but usually yes, even if sometimes initWithCoder: is called instead of the initmethod.
You can test it by simply putting a call to NSLog in the init method.

How to access delegate returned parameters outside of the delegate method?

I've got a UIViewController with a UIPicker on it and I've got the - (void)sourcePickerViewController:(SourcePickerViewController *)controller etc... which returns several bits of data (the etc...) to it's delegate. Inside the delegate method, I see the values I want and can output them via NSLog but I can't figure out how to use them elsewhere in the code. In the same UIViewController that has that delegate method in it, I have another method that should update some UITextFields based on the data returned, but I get errors like dataVariableName undeclared.
Any suggestions?
When the delegate method is called store references to the variables in your delegate class, then you will be able to use them in other methods.

Automatically Loading XIB for UITableViewController

Ran into something interesting, want to know if I'm doing something wrong or if this is the correct behavior.
I have a custom UITableViewController. I ASSUMED (first mistake) that if you initialize as such:
[[CustomTableController alloc] init];
it would automatically load from a XIB of the same name, CustomTableController.xib, if it is in the same directory and such.
HOWEVER
This does not work; doesn't load the XIB. BUT, if I change the parent class of my controller from 'UITableViewController' to 'UIViewController', EVERYHTING WORKS FINE!
Calling:
[[CustomTableController alloc] init];
loads the controller and view from my xib.
Am I doing something wrong? Is this a bug? Expected behavior?
Most of the classes in Cocoa Touch list a "designated initializer" that you're supposed to call from your init methods when you subclass them. When you create your own custom class, it's a good idea to check the documentation to find the designated initializer for your superclass. When you initialize the class using some other initializer from a more general superclass (which you're doing by calling - [NSObject init] in this case), you rob your direct superclass of its opportunity to properly initialize its state. Sometimes you can get away with this. Often you can't.
UIViewController's documentation states that its designated initializer is -initWithNibName:bundle:. If you call this method with a nil nibName, it will look for a nib that matches your class name. The behavior of -init is undocumented for UIViewController. Based on the behavior you're seeing, it seems like it may be calling [self initWithNibName:nil bundle:nil], but it would be safer to call initWithNibName:bundle: directly rather than relying on this undocumented behavior.
UITableViewController only defines a single initializer, -initWithStyle: (although it doesn't specify this method as the designated initializer). This method initializes your UITableViewController without using a nib, which is usually fine. Since you don't add subviews to a UITableView, there usually isn't much to be gained by configuring your UITableViewController via a nib.
If decide you want to configure your UITableViewController via a nib anyway, the documentation tells us that we can safely bypass -initWithStyle: and call UIViewController's initWithNibName:bundle: method. Here is what the documentation tells us about how our UITableView and its controller will be initialized in each case:
If a nib file is specified via the initWithNibName:bundle: method (which is declared by the superclass UIViewController), UITableViewController loads the table view archived in the nib file. Otherwise, it creates an unconfigured UITableView object with the correct dimensions and autoresize mask. You can access this view through the tableView property.
If a nib file containing the table view is loaded, the data source and delegate become those objects defined in the nib file (if any). If no nib file is specified or if the nib file defines no data source or delegate, UITableViewController sets the data source and the delegate of the table view to self.
In summary, the documentation for most Cocoa Touch classes either specify a single designated initializer or a handful of initializers that you can call safely from your subclasses. Always refer to the documentation for your superclass to figure out which initializer your subclass should call.

setup coredata, before appdelegate loads my mainWindow.xib

I have setup coredata in my appDelegate, but it first loads the mainWindow.xib and the corresponding controllers+views in that xib file. Those controllers need to have a managedObjectContext to load properly. And after the xib is unarchived it runs the code in my appDelegate.
How can i setup my coredata and then load the mainWIndow.xib? Or just make sure coredata is initialized properly before unarchiving my mainWindows.xib?
You could override awakeFromNib on your UIApplicationDelegate subclass, and setup Core Data there. This method will be called once all objects has been unarchived from your nib file, but before their instances begin to do their work. See awakeFromNib as your last chance to tweak any behavior before the instances start running.
Observe:
When overriding awakeFromNib you must call [super awakeFromNib], or else your superclass might not initialize properly.
The order of the calls to awakeFromNib is undefined, so you may never send messages to any other objects from the same Nib from within awakeFromNib. As a bonus this also means that awakeFromNib is guaranteed to run before any other object in the same Nib needs your services and sends any messages to you.