Reputation: 1941
I have a project on iPhone with iOS4.
A instance variable of app delegate is a dictionary with global readonly data loaded from a plist when app starts.
CalculatorAppDelegate.h
#import <UIKit/UIKit.h>
@class MainViewController;
@interface CalculatorAppDelegate : NSObject <UIApplicationDelegate> {
NSDictionary *RGBSpacesDictionary;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain, readonly) NSDictionary *RGBSpacesDictionary;
@property (nonatomic, retain) IBOutlet MainViewController *mainViewController;
@end
CalculatorAppDelegate.m
#import "CalculatorAppDelegate.h"
#import "MainViewController.h"
@implementation CalculatorAppDelegate
@synthesize mainViewController=_mainViewController;
@synthesize RGBSpacesDictionary;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// load plist
NSString* plistPath1 = [[NSBundle mainBundle] pathForResource:@"RGBSpaces" ofType:@"plist"];
RGBSpacesDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath1];
etc.
}
Then in MainViewController i am able to successfully reading the dictionary in viewDidLoad
MainViewController.h
@class CalculatorAppDelegate;
@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
CalculatorAppDelegate *appDelegate;
}
@property (nonatomic, retain) CalculatorAppDelegate *appDelegate;
etc.
}
MainViewCOntroller.m
#import "CalculatorAppDelegate.h"
@implementation MainViewController
@synthesize appDelegate;
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate = [[UIApplication sharedApplication] delegate];
RGBSpacesCount = (int) [appDelegate.RGBSpacesDictionary count];
}
In viewDidLoad it is all OK, I can read my dictionary as appDelegate.REGSpaceDictionary.
The problem is with another method of MainVievController called when a button is pressed
- (IBAction) RGBSpaceButtonPressed {
NSLog(@"appDelegate.RGBSpacesDictionary %@", appDelegate.RGBSpacesDictionary);
etc.
}
At this time calling the dictionary (for example with a NSLog) return in a crash.
Can someone help me? Thank you.
Upvotes: 1
Views: 835
Reputation: 38728
In this line
RGBSpacesDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath1];
you are assigning an autoreleased
object straight to the ivar so there is no guarantee how long it will stay around for. You should be assigning a non autoreleased object or going through the setter
// Going through the setter
self.RGBSpacesDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath1];
// OR
// Non assigning a non autoreleased object
RGBSpacesDictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath1];
To use the setter you would have to redeclare the property
in an extension at the top of the app delegate's .m
file like this
@interface CalculatorAppDelegate ()
@property (nonatomic, retain, readwrite) NSDictionary *RGBSpacesDictionary;
@end
...
The rest of your implementation
Upvotes: 3
Reputation:
Try to retain the dictionary in app delegate. It must be deallocated at some point, because you get an autoreleased one and you didn't use the property to set it.
// here you must retain the dictionary
[[NSDictionary dictionaryWithContentsOfFile:plistPath1] retain];
Of course don't forget to release it later in dealloc.
Upvotes: 1