iOS MVC - How to pass data from model to controller?

Я провел немало исследований по этому вопросу, но у меня возникли проблемы с моей психикой. Я работаю над Objective-C для приложения для iOS

Вот мои настройки:

  1. Контроллер представления получает текст из представления (пользовательский ввод) и передает этот текст в MethodA модели.

  2. Метод A в модели работает с вводимым текстом и получает выходные данные (например, ищет в Google этот текст). Он выполняет поиск, используя метод dispatch_async, который вызывает селектор для MethodB в модели.

  3. MethodB анализирует выходные данные и помещает все результаты в NSMutableArray

  4. Мой вопрос здесь: как я могу передать этот 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]

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

Но если оба являются методами внутри контроллера представления, почему бы просто не обновить представление внутри метода вместо передачи его другому методу?

Другие вопросы по тегам