Мне интересно, как правильно сделать копию объекта, определенного в делегате приложения или одноэлементном объекте. Короче говоря, я делаю приложение, которое требует от пользователя входа в систему. Это представление входа в систему представляет собой просто контроллер модального представления поверх «реального» приложения, которое состоит из контроллера панели вкладок и некоторых контроллеров табличного представления. После успешного входа в систему отправляется запрос данных на удаленный сервер, а контроллер модального представления закрывается, открывая контроллер панели вкладок и табличные представления, содержащие XML-данные. Для анализа входящих данных я создал одноэлементный объект с именем DataParser, который имеет интерфейс
...
@interface DataParser : NSObject {
// Data objects that hold the data obtained from XML files
NSMutableDictionary *personnel;
NSMutableDictionary *schedule;
NSMutableDictionary *today;
}
@property (nonatomic, retain) NSMutableDictionary *personnel;
@property (nonatomic, retain) NSMutableDictionary *schedule;
@property (nonatomic, retain) NSMutableDictionary *today;
...
Теперь в этих словарях я храню (изменяемые) словари и массивы, содержащие объекты NSString с проанализированными XML-данными. Поскольку я не хочу изменять эти исходные объекты, содержащие проанализированные данные (то есть я хочу изменять их только на этапе входа в систему, но не в любом из контроллеров табличного представления), я создаю новый объект словаря, который содержит копия содержимого одного из приведенных выше словарей в каждом контроллере tableview. Так, например, в loadView контроллера представления с именем ScheduleViewController у меня есть
...
@interface ScheduleViewController : UITableViewController {
NSDictionary *copyOfSchedule;
}
@property (nonatomic, retain) NSDictionary *copyOfSchedule;
...
@end
@implementation ScheduleViewController
@synthesize copyOfSchedule;
- (void)loadView {
[super loadView];
DataParser *sharedSingleton = [DataParser sharedInstance];
self.copyOfSchedule = [NSDictionary dictionaryWithDictionary:sharedSingleton.schedule];
}
...
Теперь это работает нормально. Однако единственная трудность возникает, когда пользователь «выходит из системы», что влечет за собой возвращение контроллера модального представления входа в стек. Когда пользователь снова нажимает кнопку входа в систему, на сервер отправляется новый запрос данных XML, и словари в одноэлементном объекте обновляются (новыми) данными (я проверяю, содержат ли они какие-либо данные, если да, я вызываю removeAllObjects перед снова заполняя их вновь проанализированными данными). На этом этапе словари во всех контроллерах представления также должны быть обновлены, однако я не совсем уверен, как это сделать правильно. Я заметил, что в этом случае loadView не всегда вызывается снова, поэтому для этого я добавил тот же код, что и выше, в loadView для каждого метода viewWillAppear. Однако после перехода туда и обратно между различными представлениями или перехода назад и вперед между дочерними представлениями табличного представления пару раз я получаю сообщение об ошибке EXC_BAD_ACCESS. Я подозреваю, что это связано с неправильным сохранением копий исходных словарей, но, похоже, я не могу найти решение этой проблемы. Вместо использования DictionaryWithDictionary, который, как я подозреваю, в любом случае является неправильным, я также попробовал другой подход, когда вместо использования объектов типа NSDictionary в ScheduleViewController я использую NSMutableDictionary. Так:
...
@interface ScheduleViewController : UITableViewController {
NSMutableDictionary *copyOfSchedule;
}
@property (nonatomic, retain) NSMutableDictionary *copyOfSchedule;
...
@end
@implementation ScheduleViewController
@synthesize copyOfSchedule;
- (void)loadView {
[super loadView];
DataParser *sharedSingleton = [DataParser sharedInstance];
self.copyOfSchedule = [[NSMutableDictionary alloc] initWithDictionary:sharedSingleton.schedule];
}
- (void)viewWillAppear {
DataParser *sharedSingleton = [DataParser sharedInstance];
[self.copyOfSchedule removeAllObjects];
[self.copyOfSchedule addEntriesFromDictionary:sharedSingleton.schedule];
[self.tableView reloadData];
}
...
Но это не избавляет от ошибок EXC_BAD_ACCESS. Короче говоря, как лучше всего сделать независимые копии объектов, определенных в одноэлементном объекте или делегате приложения, которые можно динамически обновлять по запросу? Поскольку я уже довольно увлечен проектом и многое происходит, я понимаю, что мой вопрос может быть немного расплывчатым. Тем не менее, я надеюсь, что есть кто-то, кто мог бы просветить меня как-то.