Swift 附加到类内部的数组实际上不是附加到调用对象?

Swift 附加到类内部的数组实际上不是附加到调用对象?,swift,xcode,Swift,Xcode,我在ViewController.swift中实例化一个对象,然后调用该对象的一个方法,以便将值附加到其成员之一。然而,当我试图访问新附加的值时,我收到了一个“索引超出范围错误”。更具体地说,我试图将newProduct:Product附加到类成员products:[Product]方法getAllProducts()和populateProducts中。但是在我附加之后,ViewController中的初始调用对象client:ThreeDCartAPIClient实际上并不保留来自内部类方法

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

我尝试在类方法中的任何地方使用“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

    }
}

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

protocol JsonResponseProtocol: class {
    func asyncTaskCompleted()
}
在ThreeDCartAPIClient类中写入:

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

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

然后在viewController.swift中写入以下内容:

extension ViewController: JsonResponseProtocol{
 func asyncTaskCompleted(){

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

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

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

protocol JsonResponseProtocol: class {
    func asyncTaskCompleted()
}
在ThreeDCartAPIClient类中写入:

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

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

然后在viewController.swift中写入以下内容:

extension ViewController: JsonResponseProtocol{
 func asyncTaskCompleted(){

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


为了更好地实践,您可以从ThreedCartApicClient类发送asyncTaskCompleted()中的数据数组。

您正在调用异步API。它们在您完成所有操作后的某个不确定的时间运行它们的完成处理程序(或者可能永远不会)。您不能在启动流程后立即访问值,您必须等待它完成。谢谢,我有一种感觉,这可能就是它。您知道有什么方法可以在访问对象之前等待API调用完成吗?您可以在
populateProducts
方法中使用
DispatchGroup
,我认为这会对您有所帮助。@BrandonMain有多种方法,但不幸的是,没有一种方法的状态是“全部结束”。您可以使用委托模式、完成处理程序、NSNotificationCenter或PromiseKit或(我最喜欢的)RxSwift之类的并发库。(你可以用谷歌搜索所有这些东西)。最容易开始使用的是完成处理程序,但是Rx是调用异步API时最可扩展的。它们在您完成所有操作后的某个不确定的时间运行它们的完成处理程序(或者可能永远不会)。您不能在启动流程后立即访问值,您必须等待它完成。谢谢,我有一种感觉,这可能就是它。您知道有什么方法可以在访问对象之前等待API调用完成吗?您可以在
populateProducts
方法中使用
DispatchGroup
,我认为这会对您有所帮助。@BrandonMain有多种方法,但不幸的是,没有一种方法的状态是“全部结束”。您可以使用委托模式、完成处理程序、NSNotificationCenter或PromiseKit或(我最喜欢的)RxSwift之类的并发库。(你可以用谷歌搜索所有这些东西)。最容易开始的是一个完成处理程序,但Rx是最可扩展的这一行
client.jsonresponseedelegate=self
给了我一个“预期声明”错误你能写/给出更新的ThreeDCartAPIClient类的屏幕截图吗?你在哪里写的:client.jsonresponseedelegate=self?您可以在以下时间之后编写:super.viewDidLoad()在super.viewDidLoad()之后添加它,但我仍然得到“索引超出范围错误”:(好的,我将
featuredButton1Image.image=client.products[0].mainImage
移动到
asyncTaskCompleted()中
方法,并且它正在工作,非常感谢!这一行
client.jsonresponseedelegate=self
给了我一个“预期声明”错误。您可以编写/给出更新的3dcartapiclient类的屏幕截图吗?您在哪里编写的:client.jsonresponseedelegate=self?您可以在:super.viewDidLoad()之后编写它在super.viewdiload()之后添加它可以工作,但我仍然得到“索引超出范围错误”:(好的,我将
featuredButton1Image.image=client.products[0].mainImage
移动到
asyncTaskCompleted()
方法中,并且它工作正常,非常感谢!