iOS MVC - How to pass data from model to controller?
Я провел немало исследований по этому вопросу, но у меня возникли проблемы с моей психикой. Я работаю над Objective-C для приложения для iOS
Вот мои настройки:
Контроллер представления получает текст из представления (пользовательский ввод) и передает этот текст в MethodA модели.
Метод A в модели работает с вводимым текстом и получает выходные данные (например, ищет в Google этот текст). Он выполняет поиск, используя метод dispatch_async, который вызывает селектор для MethodB в модели.
MethodB анализирует выходные данные и помещает все результаты в NSMutableArray
Мой вопрос здесь: как я могу передать этот NSMutableArray обратно в контроллер, чтобы я мог показать его в представлении?
Извините, если ответ на мой вопрос очень прост / очевиден. Я новичок в Objective-C
5 ответов
Я предполагаю, что передача объекта-делегата, который привязывается к методу-селектору, и вызов этого метода с обработанными данными будет хорошим способом для получения структуры, связанной с алгоритмом "Лоусли", которой заслуживает ваша программа. Вы знакомы с этой концепцией, или я выкопаю несколько примеров кода для вас?
ОБНОВЛЕНИЕ: примеры кода
Итак, я бы, вероятно, использовал вызывающий класс, скажем, MyViewController
, чтобы реализовать callbackMethod, myCallbackMethod
следующее:
-(void) myCallbakcMethod: NSMutableArray* array {
//DoWhatever with the returned data
}
Суть в том, чтобы получить результат, переданный обратно этому методу, когда вычисление закончено. Так в вашем MyViewController
куда вы звоните MethodA
Вы передаете ссылку на делегат для обработки результата, Namly self
,
//From this:
[MyModel methodA:param1]
//To:
[MyModel methodA:param1:self]
MyModel
s methodA
а также methodB
нужно будет добавить параметр (id)delegate
и передать это между вызовами.
В methodB
где данные myArray
готов сделать следующий звонок:
if([delegate respondsToSelector:@selector(myCallbackMethod:)]])
[observer performSelector:@selector(myCallbackMethod:) withObject:myArray];
Каждый раз, когда я хочу выполнить асинхронную обработку, и эти вещи должны вернуться в пользовательский интерфейс, я делаю одно из двух:
1. Use NSNotification to tell anyone who cares that the work is complete
2. Use a delegate property on the worker and a @protocol
1 NSNotification
Объект модели должен задокументировать в своем файле.h, что он запускает уведомления, когда происходят определенные вещи; например, когда часть модели была обновлена. Когда ViewController инициализирует объект модели, он должен настроить себя в качестве наблюдателя документированного уведомления и реализовать обратный вызов, который обновляет пользовательский интерфейс.
2 делегирование и @protocol
Создайте @protocol, такой как @protocol FooModelUpdateDelegate
с методом правильно названным, таким как fooObjectDidUpdate:(Foo *)object;
, а затем класс модели имеет свойство делегата как id<FooModelUpdateDelegate> updateDelegate
и ViewController устанавливает себя в качестве этого делегата, и я уверен, что вы можете выяснить остальное.
На ваш взгляд контроллер:
// your controller code
...
[myModel getSearchResult:searchKeyword receiver:self action:@selector(responseReceived:)];
}
- (void)responseReceived:(MyModel *)model
{
NSArray *searchResult = model.searchResult;
[model release], model = nil;
// some view actions, for instance update your table view
...
}
В вашей модели:
...
- (id)getSearchResult:(NSString *)searchKeyword receiver:(id)aReceiver action:(SEL)receiverAction {
self.receiver = aReceiver;
self.action = receiverAction;
// some async actions
}
В асинхронном приемнике ответа:
...
[self.receiver performSelector:self.action withObject:self];
}
Если я не понимаю ваше описание, похоже, что ваш "модельный" класс делает больше, чем должен. В этом случае он выполняет хотя бы часть работы вашего контроллера. Мое предложение состояло бы в том, чтобы сложить methodA и methodB в контроллер представления (или другой класс контроллера). Метод B все еще может установить свойство NSMutableArray экземпляра "model", если это необходимо (или пропустить этот шаг, если это не так).
-(void)methodA {
NSMutableArray *someArray = ...
[self methodB:someArray];
}
-(void)methodB:(NSMutableArray*)array {
NSLog(@"%@", array);
// do something with the array, like update the view
}
Но если оба являются методами внутри контроллера представления, почему бы просто не обновить представление внутри метода вместо передачи его другому методу?