It looks like you've made some bad design choices in your application. Not only are you calling down to the app delegate to get the dbh, but you also seem to have a method there that responds to an action message (settingsButton:
). Generally, the app delegate is there to be the application's delegate - responding to delegate methods. It's a sign of an inexperienced developer when it does more than that; I frequently see new developers use the app delegate as a convenient singleton object where they can stash data or methods instead of doing it in a more object oriented fashion.
It doesn't help that the Xcode application template initialises the Core Data Stack in the AppDelegate, and many tutorials use the delegate as storage because it keeps the project focussed on the subject of the tutorial rather than increasing complexity by doing things the way they would be done in the real world.
Remember, you want the delegate to do as little as possible. So let the app delegate set up the bare minimum number of objects, hook them up together and get out of the way.
In your case I see two things that you could be doing better. Rather than setting up a protocol to call down to your app delegate to get an object, just send it up the stack to the view controller. And secondly, you have an action method in your application delegate which would be better off in a view controller instead. Since I don't want to get too much into the second, and as your question is about sharing objects; here's how to pass the object up the stack without using a protocol.
in AppDelegate.m
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// This is okay, although it's preferable to be explicit with properties
self.dbh = [[dbHandler alloc] init];
...
}
- (IBAction)settingsButton:(id)sender {
if(!self.settingsWindowController){
self.settingsWindowController = [[SettingsWindowController alloc] initWithWindowNibName:@"SettingsWindow"];
// It already has a property for the dbh, just give it to it
self.settingsWindowController.dbh = self.dbh;
}
[self.settingsWindowController showWindow:self];
self.settingsWindowController.delegate = self;
}
// And you don't need this, or the protocol
//-(dbHandler*)sendDBobject{
// return dbh;
//}
Why is this better? There is a principle of "tell, don't ask". In this case you are telling the settings view controller what the dbh is, not making it ask some other object. Also, you are no longer coupled to an App delegate which conforms to a protocol, which means the controller is less coupled to other objects in your app. Imagine you were to unit test your settings view controller, it's so much easier to just give it the object it wants, rather than setting up the infrastructure for it to ask for things.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…