I have a problem with the init() method of a standard NSObject. I wrote a class (EFAPersistence) which is a subclass of NSObject. EFAPersistance has a attribute called efaDatabase.
EFAPersistence.h
@interface EFAPersistence : NSObject {
FMDatabase * efaDatabase;
}
@property (assign) FMDatabase * efaDatabase;
Everytime an instance of EFAPersistance is created I want to assign efaDatabase a value from my开发者_如何学Go AppDelegate.
EFAPersistence.m
@implementation EFAPersistence
@synthesize efaDatabase;
- (id)init {
if (self = [super init]) {
efaDatabase = [[NSApp delegate] efaDatabase];
}
return self;
}
@end
This way of assigning does not work. But it works if I put the code in a normal method. So I am sure that efaDatabase is correctly instantiated in my AppDelegate. It's just not working in my init() method. That's why I have the feeling that NSApp is not working inside the init() method.
That's how the important AppDelegate code looks like.
AppDelegate.h
@interface AppDelegate : NSObject <NSApplicationDelegate> {
FMDatabase * efaDatabase;
}
AppDelegate.m
- (id)init {
if (self = [super init]) {
NSString * databasePath =
[[NSBundle mainBundle] pathForResource:@"efa" ofType:@"sqlite"];
self.efaDatabase = [FMDatabase databaseWithPath:databasePath];
if (![efaDatabase open]) {
NSLog(@"Couldn't open database: %@", databasePath);
// TODO: Create a database here
}
self.db = [[EFAPersistence alloc] init];
}
return self;
}
As you can see I am calling the init method. I also affirmed this by using NSLog(). init() is called. The attribute I am trying to assign in EFAPersistence is also created before init() is called.
To sum everything up:
How can I make this work within the init() method so I do not have to write boiler plate code in all my methods of EFAPersistence?
It looks to me that your AppDelegate is unset when you try to create the EFAPersistance
object the first time. This is on below line in AppDelegate.m
self.db = [[EFAPersistence alloc] init];
I imagine the app delegate is set after the init
is done (returned).
This way of assigning does not work. But it works if I put the code in a normal method. So I am sure that efaDatabase is correctly instantiated in my AppDelegate. It's just not working in my init() method. That's why I have the feeling that NSApp is not working inside the init() method.
NSApp works fine.
Quoting epatel:
I imagine the app delegate is set after the init is done (returned).
Correct. The nib loader completely instantiates each object (including the app delegate, if it's in a nib), then sets it as the value of any properties it's connected to. These are two separate operations; it will not set a not-yet-initialized object as the application delegate.
Quoting you (Jens) again:
The question is how to assign
efaDatabase
in EFAPersistences only once . There are other methods like awakeFromNib and viewDidLoad etc. But those are not available in a plain NSObject subclass.
Incorrect. awakeFromNib
is sent to every object in a nib after the object has been initialized.
That said, I'm curious as to why you have EFAPersistence in a nib. From its name, it doesn't sound interface-related. Shouldn't the app delegate own the EFAPersistence, and the EFAPersistence own the database directly?
精彩评论