2016-04-02 15 views
0

私はMVCモデルでアプリケーションを構築しています。 私は遅延読み込み技術を使用して変数を埋めます。 (モデル) そして、この変数は1つのUIViewController(コントローラ)によって行われていますスイフト:レイジーロード変数対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() { 

これは、私は、本当に深刻な問題です私の目的を完全に満たすためにどのような技術が使用されるのか混乱させますか?

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

override func viewDidLoad() { 
    update() 
} 

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

実は、私は強く、この場合には、クラスの機能を使用することをお勧めしません(そして多く:あなたのUIViewControllerで

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 
    } 

答えて

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

または私はネイティブスウィフトコレクションを使用することもお勧めしたい

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

ビット「Swiftier」タイプの代わりにNSArrayNSDictionary

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

それは非同期アクションですが、ちょうどここにコールバックを使用他のケースもそうです)、それはスケーラブルではなく、しばらくしても維持するのが難しいです。

+0

のデータ・ソース・アレイを想定している私はこのエラーを受け取りました;代わりに 'Index'型の値を使用するのですか? 'これは完了ブロックですか? 'allQuotes'メソッドを終了すると、' callback() 'が実行されます。 – TomSawyer

+0

'return quotes'行は常に空の配列を返すので、これは機能しません。あなたは、コールバックブロックに入れられた配列を返す必要があります – vadian

+0

@Eugene私はそれを試してみましたが動作しません。 – TomSawyer

0

まず、viewdidLoad内部から関数を呼び出します。次に、ブロックまたはデリゲートを使用して、コントロールをViewControllerに渡します。私はブロックapprochを好むだろう。完了ブロックと失敗ブロックを持つことができます。補完ブロックではビューをリロードすることができ、失敗した場合はalertcontrollerを使うか何もしません。

ブロックの例としてAFNetworkingがあります。

+0

なぜ私は 'viewdidLoad'の内部から関数を呼び出さなければなりませんか?そのメソッドの外に変数を宣言することの違いは何ですか? – TomSawyer

+0

メソッドが非同期であるため、実際にはブロックまたはデリゲートを使用する必要があります。あなたの方法がまっすぐであっても、うまく働いていたであろう価値を返すならば。 –

関連する問題