【问题标题】:iPhone: Using a NSMutableArry in the AppDelegate as a Global VariableiPhone:在 AppDelegate 中使用 NSMutableArry 作为全局变量
【发布时间】:2011-02-08 22:44:36
【问题描述】:

我想要完成的是在 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。所以它似乎没有得到正确更新。有什么建议吗?

【问题讨论】:

    标签: iphone uiviewcontroller nsmutablearray datamodel


    【解决方案1】:

    这里有几个问题:

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

    请尝试:

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

    【讨论】:

      【解决方案2】:

      一些事情:

      首先,在您的应用委托中,您需要确保在任何对象尝试访问它之前初始化数组。客户获取者对此有好处。

      -(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;
      }
      

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

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

      在视图控制器中:

      @property(nonatomic,assign) NSMutableArray *globalClasses;
      

      然后每次引用它时,请确保使用 self 表示法:

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

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

      【讨论】:

      • 我采用了您的第二种方法来制作包装类。它更干净,更容易理解。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      相关资源
      最近更新 更多