Передача объектов между классами - PullRequest
2 голосов
/ 07 августа 2011

В моем AppDelegate я загружаю некоторые данные из Интернета и сохраняю их в виде массива. Я хочу, чтобы один из моих ViewControllers получил доступ к этому массиву. Как бы я поступил так? Это хорошая ситуация для реализации делегата или протокола? Если да, может кто-нибудь порекомендовать хороший учебник для этого?

Спасибо

EDIT:

Обратите внимание, что данные обновляются при каждом запуске, поэтому нет необходимости в Core Data или списках. Кроме того, данные являются пользовательскими объектами, которые я создал, поэтому они не могут быть сохранены, например, в plist.

Ответы [ 5 ]

3 голосов
/ 07 августа 2011

У вас есть 2 варианта:

  1. Реализация протокола делегата
  2. Использование NSNotifications

Преимущества / недостатки каждого из них хорошо изложены в этомвопрос и ответ: Делегаты v Уведомления

Поскольку уведомления легче реализовать и их вполне может быть достаточно для ваших нужд, вы можете реализовать их, выполнив следующие шаги:

  1. В классе, в который вы загружаете данные: когда данные загружены и массив заполнен, включите следующие строки:

NSDictionary *dict = [NSDictionary dictionaryWithObject:array forKey:@"Data"]; [[NSNotificationCenter defaultCenter] postNotificationName:@"DataDownloaded" object:self userInfo:dict];

В классе, в который вы хотите получить данные:

2.1 Добавьте следующую строку в ваш метод viewDidLoad:

`[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataDownloaded:) name:@"DataDownloaded" object:nil];

2.2 Создайте селектор dataDownloaded:

  • (void) dataDownloaded: (NSNotification *) note {

    NSDictionary *dict = note.userInfo; NSArray *dataArray = [note.userInfo objectForKey:@"DataDownloaded"];

2.3 Добавьте следующую строку в dealloc иviewDidUnload:

[[[NSNotificationCenter defaultCenter] removeObserver:self];
0 голосов
/ 07 августа 2011

Вы можете отправить уведомление, если представитель приложения получил новые данные, и все заинтересованные контроллеры будут знать, что им нужно обновить представления.Для этого вы можете использовать NSNotificationCenter.Например,

- (void)newDataLoaded {
  NSDictionary *userInfo = [NSDictionary dictionaryWithObject:arrayOfData forKey:@"data"];
  [[NSNotificationCenter defaultCenter] postNotificationName:@"data updated notification name" object:nil userInfo:userInfo];
}

Если какой-либо контроллер заинтересован в обновлении данных, он должен подписаться на это уведомление как можно скорее:

- (void)viewDidLoad {
  ...
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataUpdatedNotificationHandler:) name:@"data updated notification name" object:nil];
  ...
}

Не забудьте отписаться от уведомлений, если вы этого не сделаетенужно это.Для этого используйте методы [[NSNotificationCenter defautCenter] removeObserver:self] в viewDidUnload и dealloc.

- (void)dataUpdatedNotificationHandler:(NSNotification*)notification {
  NSArray *data = [[notification userInfo] objectForKey:@"data"];
  // update your view here
}
0 голосов
/ 07 августа 2011

Если вы хотите сохранить свой массив в делегате, то в любом представлении вам нужно создать ссылку на ваш делегат, и вы можете получить доступ к вашему массиву в этом представлении, например:

, в другом представлении вы должны написать:в .h файле

#import "YourDelegateFile.h" и объявите переменную

YourDelegateFile *appDelegate ;

в своем файле .m:

- (void) viewDidLoad
{
   appDelegate = (YourDelegateFile *)[UIApplication sharedApplication] delegate];

   NSArray *aArray = [appDelegate yourArrayName]; //yourArrayName is an array that you have declare in delegate 
}

надеюсь, это поможет вам.

0 голосов
/ 07 августа 2011

вам просто нужно получить доступ к данным, хранящимся в приложении applegate. Я не думаю, что это лучшее решение вашей проблемы, но для того, чтобы делать все так, как вы хотите.

поэтому объявите свою собственность в вашем файле Appdelegate .h

NSMutableArray* myArray_;

затем добавьте свойство в тот же файл

@property (nonatomic, retain) NSMutableArray* myArray;

в файле .m

убедитесь, что вы синтезируете свою собственность

@synthesize myArray = myArray_;

где-нибудь в вашем файле appdelegate .m вы установите значение

тогда в других местах вашего кода вы можете получить доступ к свойству в приложении applelegate, например, так:

MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate
NSMutableArray* localArray = appDelegate.myArray;

Обратите внимание, для хорошей инкапсуляции вы должны действительно использовать NSArray, но я использовал mutable, чтобы код был коротким.

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

0 голосов
/ 07 августа 2011

Вы можете хранить данные в файле plist и использовать их во всех контроллерах представления. Таким образом, вам не нужно беспокоиться о размере данных (так как вы будете загружать их по требованию и немедленно освобождать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...