Swift - 通过块传递结构数组并检索成员



我有一个完成块,它将一个结构数组的数据交给另一个视图控制器。

此数据在 viewDidLoad 中接收,如下所示:

  var packArray = [Any]()// the block is returning Any
    override func viewDidLoad() {
        super.viewDidLoad()
             BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self) { (result) in     
                  self.packArray = [result]
             }
    }

打印此self.packArray在一行上返回以下内容,我现在不知道如何提取数据。

[[static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk00", description: "This is some text", title: "Not a murderer", image: <PFFile: 0x60000005fc80>, id: "rHITAAHJYk"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk01", description: "This is some text", title: "Addiction", image: <PFFile: 0x600000240300>, id: "uGHHpPF89e"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk02", description: "This is some text", title: "Towels are noisy", image: <PFFile: 0x600000240570>, id: "PeM7hJ4sih"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk03", description: "This is some text", title: "Class action", image: <PFFile: 0x6000002407e0>, id: "LoSXT2PFoS"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk04", description: "This is some text", title: "Beer", image: <PFFile: 0x600000240a50>, id: "vxEsd13twt"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk05", description: "This is some text", title: "Not again...", image: <PFFile: 0x600000240cc0>, id: "JNqaAgtdRb"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk06", description: "This is some text", title: "Foreign cars", image: <PFFile: 0x600000240f30>, id: "Hb16TDXGbz"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk07", description: "This is some text", title: "Skin problems", image: <PFFile: 0x6000002411a0>, id: "MUYDMnJCrU"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk08", description: "This is some text", title: "Junk food", image: <PFFile: 0x600000241410>, id: "yowAfJlcmr"), static ParseStarterProject_Swift.BuildArray.(buildArrayFromQuery (queryForCollection : Swift.String, sender : __ObjC.UIViewController, completeBlock : (Any) -> ()) -> ()).(collectionStruct #1)(name: "pk09", description: "This is some text", title: "Delusion", image: <PFFile: 0x600000241680>, id: "TiLAKBPmaD")]]

以前我使用:

cell.labelCell.text = self.packArray[indexPath.item].packDescription

但现在返回没有成员包描述。我可能会使用字符串处理并造成混乱,但必须有更好的方法来将数据作为实际数组获取。 我知道我将其转换为 Any,但找不到另一种通过完成块从结构数组获取数据的方法。

-----编辑----

在创建数组的类中,有一个结构体,以及来自结构体的数组结果作为任何通过完整块传递

class func buildArrayFromQuery(queryForCollection: String,
       sender: UIViewController, 
       completeBlock: @escaping (_ result: Any) -> Void) {
    struct collectionStruct {
        var name : String
        var description : String
        var title : String
        var image : PFFile
        var id: String
    }
        var collectionArray = [collectionStruct]()

然后从 PFQuery 创建,结果数组通过完成处理程序传回

query.findObjectsInBackground(block: { (objects, error) in
if error != nil {
    print(error!)
} else if let packs = objects {

    for object in packs {
        print(fromName)
        print(object)
        let arrayName = object.object(forKey: fromName) as! String
        let arrayDescription = object.object(forKey: fromDescription) as! String
        let arrayTitle = object.object(forKey: fromTitle) as! String
        let arrayImage = object.object(forKey: fromImage) as! PFFile
        let arrayID = object.objectId as String!
        collectionArray.append(collectionStruct(name: arrayName, description: arrayDescription, title: arrayTitle, image: arrayImage, id: arrayID!))
    }
}

completeBlock(result: collectionArray)
})

您需要将查询结果强制转换为所需的类型。如果将 packArray 设置为可选,则可以直接使用

var packArray: [collectionStruct]?
self.packArray = result as? [collectionStruct]

使用该代码,如果结果无法转换为正确的数组类型,则 self.packArray 将包含 nil。

或者可以使用可选绑定:

var packArray: [collectionStruct] = []

if structsArray = result as [collectionStruct] {
  self.packArray = structsArray
}

你应该在viewDidLoad之外定义packArray:

var packArray: [collectionStruct] = []
override func viewDidLoad() {
  super.viewDidLoad()
    BuildArray.buildArrayFromQuery(queryForCollection: "Pack", 
     sender: self) { 
      (result) in 
      if structsArray = result as [collectionStruct] {
        self.packArray = structsArray
     }
}

你的代码在viewDidLoad中定义了一个局部变量packArray,这会混淆事情。我建议不要使用实例变量和同名的局部变量。

非常感谢邓肯 C 的输入,请将您的答案标记为正确,我只是想分享我如何调整它以使其工作。

在类外部定义了结构,这让我可以在完成处理程序中使用 [collectionStruct]。

struct collectionStruct {
    var name : String
    var description : String
    var title : String
    var image : PFFile
    var id: String
}
class BuildArray: UICollectionViewController {
    class func buildArrayFromQuery(queryForCollection: String, 
                  sender: UIViewController, 
                    completeBlock: @escaping (_ result: [collectionStruct]) -> Void) {

然后在查询后返回数组

completeBlock(collectionArray)

然后在另一个班级,正如邓肯C所建议的那样

if let structsArray = result as? [collectionStruct] {
     self.packArray = structsArray
}

这仍然会发出警告:

"non option expression type [collectionStruct] used in check for optionals" 

所以看看我能在这里做什么。

最新更新