2016-04-02 1 views
0

Я создаю приложение с моделью MVC. Я использую ленивую технику загрузки, чтобы заполнить переменную. (Модель) И эта переменная находится на одном UIViewController (Controller)Swift: ленивая переменная нагрузки против модели MVC?

Но я не знаю, как перезагрузить или вызвать контроллер вида, когда действие модели закончено. Вот мой код

Модель (данные ленивых нагрузки)

class func allQuotes() -> [IndexQuotes] 
    { 
     var quotes = [IndexQuotes]() 
     Alamofire.request(.GET, api_indexquotes).responseJSON { response in 
      if response.result.isSuccess && response.result.value != nil { 
       for i in (response.result.value as! [AnyObject]) { 
        let photo = IndexQuotes(dictionary: i as! NSDictionary) 
        quotes.append(photo) 
       } 

      } 
     } 

     return quotes 
    } 

И часть зрения контроллера

Индекс Класс:

UIViewController,UICollectionViewDelegate,UICollectionViewDataSource { 

    var quotes = IndexQuotes.allQuotes() 
    var collectionView:UICollectionView! 

    override func viewDidLoad() { 

Это действительно серьезный вопрос, я путают, какая техника будет использоваться для полного заполнения моей цели?

ответ

1

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

class func allQuotes(completion: ([IndexQuotes]) -> Void) 
    { 
    var quotes = [IndexQuotes]() 
    Alamofire.request(.GET, api_indexquotes).responseJSON { response in 
     if response.result.isSuccess && response.result.value != nil { 
     for photoDict in (response.result.value as! [NSDictionary]) { 
      let photo = IndexQuotes(dictionary: photoDict) 
      quotes.append(photo) 
     } 
     } 
     completion(quotes) 
    } 
    } 

Или немного «Swiftier»

... { 
    let allPhotos = response.result.value as! [NSDictionary] 
    quotes = allPhotos.map {IndexQuotes(dictionary: $0)} 
} 

Я бы рекомендовал также использовать родной Swift коллекцию типы, а не NSArray и NSDictionary

В viewDidLoad на ваш взгляд контроллер cal l allQuotes и перезагрузите представление таблицы в блоке завершения основного потока.

indexQuotes свойство, начиная со строчной буквы предполагается в качестве источника данных массив в виде таблицы

var indexQuotes = [IndexQuotes]() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    IndexQuotes.allQuotes { (quotes) in 
    self.indexQuotes = quotes 
    dispatch_async(dispatch_get_main_queue()) { 
     self.tableView.reloadData() 
    } 
    } 
} 
+0

Ну, у меня тест. Оно работает. Благодарю. Я снова собираюсь закрыть и завершить, и я нашел это http://stackoverflow.com/questions/34548180/what-is-the-best-way-to-handle-response-from-alamofire-for-a-tableview быстро. Я думаю, что это похоже на ваше решение, но они используют ключевое слово lazy перед переменной. Ты знаешь почему? – TomSawyer

+0

В упомянутой теме для создания экземпляра класса используется ленивая переменная. Здесь вы используете функцию класса, которая совершенно иная. – vadian

+0

@TomSawyer Заявление 'self.indexQuotes = quotes' должно быть выполнено в основном потоке, иначе оно не является« потокобезопасным »;) – CouchDeveloper

0

Это асинхронное действие, просто использовать функцию обратного вызова здесь:

class func allQuotes(callback:() -> Void) -> [IndexQuotes] 
    { 
     var quotes = [IndexQuotes]() 
     Alamofire.request(.GET, api_indexquotes).responseJSON { response in 
      if response.result.isSuccess && response.result.value != nil { 
       for i in (response.result.value as! [AnyObject]) { 
        let photo = IndexQuotes(dictionary: i as! NSDictionary) 
        quotes.append(photo) 
       } 
      } 

      callback() 
     } 

     return quotes 
    } 

В вашем UIViewController:

var quotes = IndexQuotes.allQuotes() { 
    self.update() 
} 
var collectionView:UICollectionView! 

override func viewDidLoad() { 
    update() 
} 

private func update() { 
    // Update collection view or whatever. 
} 

На самом деле, я настоятельно не рекомендую использовать функции класса в этом случае (и многий другие случаи тоже), он не масштабируется и с трудом поддерживается через некоторое время.

+0

Я получил эту ошибку: 'Использовать из членов«обновление»экземпляра по типу«Индекс» ; Вы имели в виду использовать значение типа «Индекс» вместо? ». Это блок завершения? Закончив метод 'allQuotes', он выполнит' callback() '? – TomSawyer

+0

Это не работает, потому что строка 'return quotes' возвращает всегда пустой массив. Вам нужно вернуть заполненный массив в блок обратного вызова – vadian

+0

@Eugene Я пробовал, но не работает. – TomSawyer

0

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

Вы можете увидеть AFNetworking в качестве примера для блоков.

+0

Почему я должен вызывать функцию из 'viewdidLoad'? в чем разница между переменной declare вне этого метода? – TomSawyer

+0

Вам действительно нужно использовать блоки или делегирование, так как ваш метод isync. Если ваш метод был прямым, вернув значение, которое было бы хорошо работает. –

 Смежные вопросы

  • Нет связанных вопросов^_^