首页 > 解决方案 > 附加到类内部的数组实际上并不是附加到调用对象?

问题描述

我在 ViewController.swift 中实例化一个对象,然后调用该对象的一个​​方法,以便可以将值附加到它的一个成员。但是,当我尝试访问新附加的值时,我收到“索引超出范围错误”。更具体地说,我试图newProduct : Productproducts : [Product]方法getAllProducts()populateProducts. 不过,在我追加之后,client : ThreeDCartAPIClientViewController 中的初始调用对象实际上并没有保留来自内部类方法的任何信息。为什么是这样?

我已经尝试在类方法中几乎所有地方都使用“self”并从初始化程序调用方法,但我一直得到相同的结果。

// ViewController.swift

import UIKit
import Alamofire
import SwiftyJSON

class ViewController: UIViewController {

    @IBOutlet weak var featuredButton1Image: UIImageView!

    let head : HTTPHeaders = [
        "SecureUrl"  : "https://someURL.3dcartstores.com/",
        "PrivateKey" : "99999999999999999999999999999999",
        "Token"      : "11111111111111111111111111111111",
        "ContentType": "application/json"
    ]
    let ENDPOINT_URL = "https://apirest.3dcart.com/3dCartWebAPI/v1/"

    var client = ThreeDCartAPIClient()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Hide the navigation bar on main screen
        viewWillAppear(true)

        // Make API request and load content
        loadInitialUI()
    }


    func loadInitialUI() {

        client.getAllProducts(url: ENDPOINT_URL, header: head)

       // ******* Here I get an "index out of range" *********** //
       featuredButton1Image.image = client.products[0].mainImage

    }
}
// ThreeDCartAPIClient.swift
import Foundation
import Alamofire
import SwiftyJSON

class ThreeDCartAPIClient {

    var products : [Product]

    init() {
        products = [Product]()
    }

    func getAllProducts(url: String, header: [String : String]) {
        Alamofire.request(url + "Products", method: .get, headers: header).responseJSON {
            response in // Start of a closure inside of Alamofire method
            if response.result.isSuccess {

                // Force unwrap the result value
                let jsonResponse = JSON(response.result.value!)

                // Populate each product field now
                self.populateProducts(json: jsonResponse)
            } else {
                print("Failure")
            }
        }
    }

    func populateProducts(json : JSON) {
        for (_, product) in json {
            let newProduct = Product()
            newProduct.sku.setSKU(json: product["SKUInfo"])
            newProduct.shortDescription = product["ShortDescription"].stringValue
            newProduct.mainImageFile = product["MainImageFile"].stringValue
            Alamofire.request("https://SomeURL.3dcartstores.com/"
                + newProduct.mainImageFile).responseData { (response) in
                if response.error == nil {

                        if let data = response.data {
                            newProduct.mainImage = UIImage(data: data)!
                        }
                }
            }

            products.append(newProduct)
        }
    }
}

标签: swiftxcode

解决方案


完成异步任务后,您将在 products 数组中获取数据。由于异步任务,您无法立即获取数据。您可以在任务完成时使用委派通知。在 ThreeDCartAPIClient.swift 文件中编写协议:

protocol JsonResponseProtocol: class {
    func asyncTaskCompleted()
}

在 ThreeDCartAPIClient 类里面写:

weak var jsonResponseDelegate: JsonResponseProtocol?

完成所有数据填充后(在您的情况下,将其写在 populateProducts() 的 for 循环之外):

self.jsonResponseDelegate?.asyncTaskCompleted()

在声明 var client = ThreeDCartAPIClient() 之后在您的 viewController 中添加以下内容(在 viewDidLoad() 中):

client.jsonResponseDelegate = self

然后在你的 viewController.swift 中写下:

extension ViewController: JsonResponseProtocol{
 func asyncTaskCompleted(){

    // if data populated successfully you can access from here 
}
}

为了更好地练习,您可以从 ThreeDCartAPIClient 类中的 asyncTaskCompleted() 中发送数据数组。


推荐阅读