问题
I am new to iPhone and objective c. I have spent hours and hours and hours reading documents and trying to understand how things work. I have RTFM or at least am in the process.
My main problem is that I want to understand how to specify where an event gets passed to and the only way I have been able to do it is by specifying delegates but I am certain there is an easier/quicker way in IB.
So, an example. Lets say I have 20 different views and view controllers and one MyAppDelegate. I want to be able to build all of these different Xib files in IB and add however many buttons and text fields and whatever and then specify that they all produce some event in the MyAppDelegate object. To do this I added a MyAppDelegate object in each view controller in IB's list view. Then I created an IBAction method in MyAppDelegate in XCode and went back to IB and linked all of the events to the MyAppDelegate object in each Xib file.
However when I tried running it it just crashed with a bad read exception.
My guess is that each Xib file is putting a MyAppDelegate object pointer that has nothing to do with the eventual MyAppDelegate adress that will actually be created at runtime.
So my question is...how can I do this?!!!
回答1:
If you create an instance of MyAppDelegate in each nib file then, yes, you do end up with a lot of different instances of the class when all the nibs load. The app delegate is not identified by class or even protocol but rather by being the object pointed to by the application instance's delegate
property. To find the true app delegate, you have have to ask the application object itself for its delegate
You should have all your view controllers descend from a parent view controller class that has an appDelegate
property. Implement something like this:
#import "MyAppDelegateClass.h"
@interface ViewControllerBaseClass :UIViewController {
MyAppDelegateClass *appDelegate;
}
@property(nonatomic, retain) *appDelegate;
@end
@implementation ViewControllerBaseClass
@synthesize appDelegate;
-(MyAppDelegateClass *) appDelegate{
self.appDelegate=(MyAppDelegateClass *)[[UIApplication sharedInstance] delegate];
return appDelegate;
}
@end
When the view controller needs the app delegate it just calls self.appDelegate
. If you want to access an attribute of the app delegate use self.appDelegate.attributeName
.
The important thing is that you ask the application for its specific delegate instance at runtime. You can't do that from a nib file.
回答2:
I'm not entirely clear what exactly you're trying to do, but it's probably a bad idea. There should only be one app delegate per application, and it should deal with behavior for the whole application. Typically, the app delegate initializes the root view controller(s) and displays them, but not much else (other than handling things like opening and saving data sources).
The view controllers (subclasses of UIViewController
) should interact with the XIBs. Having the view-specific behavior in the view controllers makes the app much easier to manage and maintain. Typically, there should be 0 or 1 XIBs per view controller (more than that is complicated). You set up the interaction with the views using the Target/Action pattern with IBOutlets and IBActions (see here for a complete guide). It's generally a bad idea to make view controllers or XIBs dependent on the app delegate (since reducing dependencies again makes the code easier to manage).
回答3:
In general you should be making a view controller for each of the views you are building, and link events to those view controllers - not the app delegate. In fact usually no event ever is wired to the app delegate from any nib file, even in the sample projects you'll note that view controllers are created and held onto by the app delegate, but it does not receive events.
来源:https://stackoverflow.com/questions/2710062/using-interface-builder-efficiently