Использование AppDelegate для глобальных данных только для чтения - PullRequest
1 голос
/ 24 июля 2011

У меня есть проект на iPhone с iOS4.

Переменная экземпляра делегата приложения - это словарь с глобальными данными только для чтения, загруженными из plist при запуске приложения.

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.
 }

Тогда в MainViewController я могу успешно читать словарь в 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];
 }

В viewDidLoad все в порядке, я могу прочитать свой словарь как appDelegate.REGSpaceDictionary.

Проблема в другом методе MainVievController, вызываемом при нажатии кнопки

- (IBAction) RGBSpaceButtonPressed {
     NSLog(@"appDelegate.RGBSpacesDictionary %@", appDelegate.RGBSpacesDictionary);

 etc.
 }

В это время вызов словаря (например, с помощью NSLog) возвращает в случае сбоя.

Может кто-нибудь мне помочь? Спасибо.

Ответы [ 2 ]

3 голосов
/ 24 июля 2011

В этой строке

RGBSpacesDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath1];

вы назначаете объект autoreleased прямо на ивар, поэтому нет никакой гарантии, как долго он будет оставаться вокруг.Вы должны назначить объект, не являющийся автоматически выпущенным, или пройти через setter

// Going through the setter
self.RGBSpacesDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath1];

// OR
// Non assigning a non autoreleased object
RGBSpacesDictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath1];

. Чтобы использовать установщик, вам нужно будет повторно объявить property в расширении в верхней части .m делегата приложения.такой файл

@interface CalculatorAppDelegate ()
@property (nonatomic, retain, readwrite) NSDictionary *RGBSpacesDictionary;
@end

...

The rest of your implementation
1 голос
/ 24 июля 2011

Попробуйте сохранить словарь в приложении делегат.В какой-то момент он должен быть освобожден, потому что вы получаете автоматически выпущенный объект, и вы не использовали это свойство для его установки.

// here you must retain the dictionary
[[NSDictionary dictionaryWithContentsOfFile:plistPath1] retain];

Конечно, не забудьте выпустить его позже в dealloc.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...