【问题标题】:Using AppDelegate for global readonly data将 AppDelegate 用于全局只读数据
【发布时间】:2011-07-25 00:48:28
【问题描述】:

我在 iOS4 的 iPhone 上有一个项目。

应用程序委托的实例变量是一个字典,其中包含在应用程序启动时从 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)返回崩溃。

有人可以帮助我吗?谢谢。

【问题讨论】:

  • 崩溃的终端输出是什么?顺便说一句:对于全局数据,您应该使用持久存储或单例。

标签: iphone ios4 delegates global-variables


【解决方案1】:

在这一行

RGBSpacesDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath1];

您将 autoreleased 对象直接分配给 ivar,因此无法保证它会保留多长时间。您应该分配一个非自动释放的对象或通过setter

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

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

要使用 setter,您必须像这样在应用程序委托的 .m 文件顶部的扩展中重新声明 property

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

...

The rest of your implementation

【讨论】:

  • 感谢您提供详细而清晰的解释。我非常感谢。
【解决方案2】:

尝试在应用委托中保留字典。它必须在某个时候被释放,因为你得到一个自动释放的并且你没有使用属性来设置它。

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

当然不要忘记稍后在 dealloc 中释放它。

【讨论】:

  • @boscarol - 太棒了!如果我的回答符合您的需要,请单击左侧的复选标记;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多