【问题标题】:Swift: Lazy load variable vs MVC model?Swift:延迟加载变量与 MVC 模型?
【发布时间】:2016-04-02 05:06:28
【问题描述】:

我正在使用 MVC 模型构建应用程序。 我使用延迟加载技术来填充变量。 (模型) 而这个变量是由一个 UIViewController (Controller)

但我不知道如何在模型操作完成时重新加载或触发视图控制器。这是我的代码

模型(延迟加载数据)

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() {

这是一个非常严肃的问题,我很困惑将使用什么技术来完成我的目的?

【问题讨论】:

    标签: ios swift model-view-controller lazy-loading


    【解决方案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)}
    }
    

    我还建议使用原生 Swift 集合类型,而不是 NSArrayNSDictionary

    在您的视图控制器中的viewDidLoad 中调用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()
        }
      }
    }
    

    【讨论】:

    • 好吧,我已经测试过了。有用。谢谢。我一直在研究关闭和完成,我发现了这个stackoverflow.com/questions/34548180/…。我认为这与您的解决方案类似,但他们在变量之前使用 lazy 关键字。你知道为什么吗?
    • 在您提到的主题中,惰性变量用于创建类的实例。在这里,您使用的是完全不同的类函数。
    • @TomSawyer 语句self.indexQuotes = quotes 必须在主线程上执行,否则它不是“线程安全的”;)
    【解决方案2】:

    首先从 viewdidLoad 内部调用函数。其次使用块或委托将控制权传递回 ViewController。我更喜欢块方法。您可以有完成和失败块。在完成块中,您可以重新加载视图,如果失败,您可以使用 alertcontroller 或什么都不做。

    您可以将 AFNetworking 视为块的示例。

    【讨论】:

    • 为什么我必须从 viewdidLoad 内部调用函数?在该方法之外声明变量有什么区别?
    • 您实际上必须使用块或委托,因为您的方法是异步的。如果您的方法直接返回一个本来可以正常工作的值。
    【解决方案3】:

    这是异步动作,这里只使用回调:

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

    实际上,我强烈不建议在这种情况下(以及许多其他情况下)使用类函数,因为它不可扩展且一段时间后难以维护。

    【讨论】:

    • 我收到了这个错误:Use of instance member 'update' on type 'Index'; did you mean to use a value of type 'Index' instead?。这是完成块吗?完成allQuotes方法后,会执行callback()?
    • 这不起作用,因为return quotes 行总是返回一个空数组。您需要在回调块中返回填充的数组
    猜你喜欢
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多