iPhone: использование NSMutableArry в AppDelegate в качестве глобальной переменной - PullRequest
0 голосов
/ 16 апреля 2010

То, что я пытаюсь сделать, - это определить NSMutableArray в AppDelegate. У меня тогда есть два UIViewControllers. Один вид отвечает за отображение массива из AppDelegate. Другое представление используется для добавления элементов в массив. Таким образом, массив начинает быть пустым. View1 ничего не отображает, потому что массив пуст. Пользователь переходит к View2 и добавляет элемент в массив в AppDelegate. Затем, когда пользователь возвращается к View1, он теперь отображает один элемент.

Вот как я пытаюсь это сделать

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

Мой другой вид

В viewDidload я установил массив в моем представлении как тот, который находится в 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 ]

2 голосов
/ 16 апреля 2010

Несколько вещей:

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

-(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.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 свойство делегата приложения, как показано выше. Это обеспечит чистоту и модульность ваших данных, чтобы вы могли безопасно использовать их в широком спектре объектов, не требующих микроуправления массивом в каждом объекте.

0 голосов
/ 16 апреля 2010

Здесь есть пара проблем:

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