iPhone:在AppDelegate中使用NSMutableArry作为全局变量

时间:2010-04-16 17:38:27

标签: iphone uiviewcontroller nsmutablearray datamodel

我想要完成的是在AppDelegate中定义一个NSMutableArray。然后我有两个UIViewControllers。一个视图负责从AppDelegate显示数组。另一个视图用于向数组添加项目。所以数组开始是空的。 View1不显示任何内容,因为数组为空。用户转到View2并在AppDelegate中向项目添加项目。然后,当用户返回View1时,它现在显示一个项目。

以下是我试图完成此操作的方法

@interface CalcAppDelegate : NSObject <UIApplicationDelegate> {
 UIWindow *window;
 UITabBarController *tabBarController;
 NSMutableArray *globalClasses;
}
@property (nonatomic,retain) NSMutableArray *globalClasses;

我的另一种观点

在viewDidload中,我将View中的数组设置为AppDelegate中的数组。努力保留价值观。

allCourses = [[NSMutableArray alloc]init];
CalcAppDelegate *appDelegate = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
allCourses = appDelegate.globalClasses;

然后我会通过添加一个新项来更新我的allCourses数组。然后尝试将AppDelegate中的数组设置为等于修改后的数组。

CalcAppDelegate *appDel = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSLog(@"Size before reset %d",[appDel.globalClasses count]);
    appDel.globalClasses = allCourses;
    NSLog(@"Size after reset %d",[appDel.globalClasses count]);

我所看到的是前面的2,后面的2。因此它似乎没有得到正确的更新。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

一些事情:

首先,在您的app委托中,您需要确保在任何对象尝试访问它之前初始化该数组。客户吸气剂对此有好处。

-(void) getGlobalClasses{
    if (globalClasses!=nil) {
        return globalClasses;
    }
    NSMutableArray *newArray=[[NSMutableArray alloc] initWithCapacity:1]; //yes, I'm old school
    self.globalClasses=newArray;
    [newArray release];
    return globalClasses;
}

现在对该属性的任何调用都保证返回一个数组。

在视图控制器中,您需要定义用于保存数组的属性。由于数组由app delegate持有并且始终存在,因此最好分配数组而不是保留它。这样,您始终知道您正在写入完全相同的数组,并且应用程序委托可以完全控制其生命周期。

在视图控制器中:

@property(nonatomic,assign) NSMutableArray *globalClasses;

然后每次引用它时都要确保使用自我符号:

self.globalClasses=//...whatever

说完这一切之后,在你的应用程序中将数组或任何其他愚蠢的数据对象裸露出来是 非常糟糕的做法 。您无法控制每段代码对数组的作用。您必须在每个添加或删除数据的位置复制所有验证代码。

最好将数组包装在自定义类中并使其受到保护,以便只能通过类方法进行更改。

像这样:

@interface MyData : NSObject {
@protected
    NSMutableArray *myDataArray;
}

-(void) addObject:(id) anObject;
-(void) removeObjectAtIndex;(NSInteger) anIndex;

@end

scratch.m

@interface scratch ()
@property(nonatomic, retain)  NSMutableArray *myDataArray;

@end

@implementation scratch
@synthesize myDataArray;

-(void) addObject:(id) anObject{
    //...code to check if anObject is a valid one to add to the array
    [self.myDataArray addObject:anObject];
}//------------------------------------addObject:------------------------------------

-(void) removeObjectAtIndex;(NSInteger) anIndex{
    //... do bounds checking and other testing to ensure no problems
    // will result from removing the object at the given idex
    [self.myDataArray removeObjectAtIndex:anIndex];
}//-------------------------------------(void) removeObjectAtIndex;(NSInteger) anIndex------------------------------------

然后将自定义类添加为app delegate的属性,如上所示。这将使您的数据保持清洁和模块化,以便您可以安全地在各种应用程序重新对象中使用它,而无需对每个对象中的数组进行微观管理。

答案 1 :(得分:0)

这里有几个问题:

allCourses = [[NSMutableArray alloc] init];
CalcAppDelegate *appDelegate = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
allCourses = appDelegate.globalClasses;
  1. 您不需要分配新数组,因为您想要保留现有数组(应用委托中的数组)
  2. 如果您正在使用属性,则需要使用self声明来保留应用委托数组
  3. 相反,请尝试:

    CalcAppDelegate *appDelegate = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
    self.allCourses = appDelegate.globalClasses;