使用什么而不是indexPath.row?对于非桌子?

时间:2016-03-24 04:16:39

标签: ios swift mkmapview cloudkit ckrecord

我正在使用mapview而不是tableview,但我不知道用什么来替换indexPath.row。

我有一个带注释的mapview,当按下注释的info按钮时,我会查询我的CK数据库并返回一个名称字段与所按下的注释名称相匹配的记录。这会返回带有单个记录的[CKRecord],因为没有匹配的名称。

此时,通过tableview,我将执行以下操作来访问数据...

let placeInfo = selectedData[indexPath.row]
let placeName = placeInfo.objectForKey("Name") as! String
let placeCity = placeInfo.objectForKey("City") as! String

但是,由于我没有使用tableview,因此我没有使用indexPath。由于我的[CKRecord]对象只包含一条记录,我以为我可以用记录的数组位置替换indexPath.row ...

let placeInfo = selectedPlace[0] //also tried 1

这些行会产生索引超出范围的错误 我已经尝试了所有我认识的东西,正如你可能想象的那样,在这一点上,我并不是很擅长迅速或编程。

这是我正在使用的完整mapView函数......

    func mapView(mapView: MKMapView, annotationView: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    let cloudContainer = CKContainer.defaultContainer()
    let publicData = cloudContainer.publicCloudDatabase

    let tappedPlace = annotationView.annotation!.title!! as String

    let predi = NSPredicate(format: "Name = %@", tappedPlace)
    let iquery = CKQuery(recordType: "Locations", predicate: predi)

    publicData.performQuery(iquery, inZoneWithID: nil, completionHandler: {
        (results, error) -> Void in

        if error != nil {
            print(error)
            return
        }

        if let results = results {
            print("Downloaded data for selected location for \(tappedPlace)")

            NSOperationQueue.mainQueue().addOperationWithBlock() {
                self.selectedPlace = results
            }
        }
    })

    let placeInfo = selectedPlace[0]
    let placeName = placeInfo.objectForKey("Name") as! String
    //returns Index out of range error for placeInfo line


    //need data before segue
    //performSegueWithIdentifier("fromMap", sender: self)
}

1 个答案:

答案 0 :(得分:2)

您的问题是,您尝试在完成处理程序实际签名之前访问selectedPlace。你的publicData.performQuery'似乎是一个异步操作,这意味着,即使在执行完成处理程序之前,控件也会从此调用中出现(在异步调用的情况下,这是预期的)。你立即到达了这条线 -

let placeInfo = selectedPlace[0]

但是数据还没有准备好,你得到了例外。现在要解决这个问题,移动位置信息提取,并在完成处理程序中执行segue代码,如图所示 -

publicData.performQuery(iquery, inZoneWithID: nil, completionHandler: {
    (results, error) -> Void in

    if error != nil {
        print(error)
        return
    }

    if let results = results {
        print("Downloaded data for selected location for \(tappedPlace)")

        NSOperationQueue.mainQueue().addOperationWithBlock() {
            self.selectedPlace = results
               if(results.count > 0){

               let placeInfo = selectedPlace[0]
               let placeName = placeInfo.objectForKey("Name") as! String
               //Do any other computations as needed.
               performSegueWithIdentifier("fromMap", sender: self)
            }
        }
    }
})

这可以解决您的问题。