我遇到了一个奇怪的错误。我正在向一个数组附加一个项目,然后通过.last属性访问该项目,但我随机得到一个“致命错误:数组索引超出范围”。
这是我的代码(在for循环中):
var thisLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
currentMarkers.append(GMSMarker(position: thisLocation))
var calle = obj["calle"] as String
var numero = obj["numero"] as String
var colonia = obj["colonia"] as String
var direccion = "\(calle) \(numero), \(colonia)"
var horarioSemanal = obj["horario_lv"] as String
var horarioSabatino = obj["horario_s"] as String
var nombre = obj["sucursal"] as String
currentMarkers.last?.icon = UIImage(named: tipo.lowercaseString)
currentMarkers.last?.title = "\(tipo) - \(nombre)"
currentMarkers.last?.appearAnimation = kGMSMarkerAnimationPop
currentMarkers.last?.snippet = direccion
错误随机显示在最后四行之一中。 我也试过通过以下方式访问它:
currentMarkers[currentMarkers.count-1].snippet = direccion
没有运气。
这段代码是一个名为fetchSucursales()的函数的一部分,我在后台调用它是这样的:
let qualityOfServiceClass = Int(QOS_CLASS_BACKGROUND.value)
let inverseQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(inverseQueue, {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.labelStatus.text = "Obteniendo marcadores..."
self.activityIndicatorUpdateMarkers.startAnimating()
})
self.fetchSucursales()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.labelStatus.text = "\(self.currentMarkers.count) marcadores encontrados."
self.activityIndicatorUpdateMarkers.stopAnimating()
})
})
如果我在主队列中运行它,每次都能正常运行:
labelStatus.text = "Obteniendo marcadores..."
activityIndicatorUpdateMarkers.startAnimating()
fetchNearbyPlaces()
labelStatus.text = "\(currentMarkers.count) marcadores encontrados."
activityIndicatorUpdateMarkers.stopAnimating()
只是我的应用程序在取出标记时会冻结,如果我这样做的话。
它是随机的,在不同的行(以及每次循环次数不同)之后的事实让我觉得它与它在后台运行有关。
我正在使用Xcode 6.1(6A1052d)。
希望你能帮助我,并提前多多谢谢!
修改
实现Nate的答案,现在错误已转移到另一行,这是我的函数的开始:
func fetchSucursales() {
mapView.clear()
currentMarkers.removeAll(keepCapacity: false)
let fileManager = NSFileManager.defaultManager()
let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(NSBundle.mainBundle().bundlePath)!
while let element = enumerator.nextObject() as? String {
if element.hasSuffix("json") {
let path = NSBundle.mainBundle().pathForResource(element.stringByDeletingPathExtension, ofType: element.pathExtension)
let jsonData = NSData(contentsOfFile: path!, options: .DataReadingMappedIfSafe , error: nil)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var sucursales : NSArray = jsonResult["markers"] as NSArray
sucursalLoop: for sucursal in sucursales {
let obj = sucursal as NSDictionary
var tipo = obj["tipo"] as String
var latitude:CLLocationDegrees = obj["latitud"]!.doubleValue
var longitude:CLLocationDegrees = obj["longitud"]!.doubleValue
if contains(searchedTypes, tipo.lowercaseString) {
//if latitude < mapRadius["norte"] && latitude > mapRadius["sur"] && longitude > mapRadius["este"] && longitude < mapRadius["oeste"] {
for var index:Int = 0; index < currentMarkers.count; ++index {
if latitude == currentMarkers[index].position.latitude && longitude == currentMarkers[index].position.longitude {
if tipo.lowercaseString == "cajero" {
continue sucursalLoop
}else {
if currentMarkers[index].title.rangeOfString("cajero") != nil {
currentMarkers.removeAtIndex(index)
}
//append
}
}
}
//Append
var thisLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let newMarker = GMSMarker(position: thisLocation)
var calle = obj["calle"] as String
//Rest of code posted before
现在错误显示在if纬度== currentMarkers [index] .position.latitude&amp;&amp; longitude == currentMarkers [index] .position.longitude {line或in if currentMarkers [index] .title.rangeOfString(“cajero”)!= nil {line。
我在for循环开始之后添加了一个println(“(currentMakers.count)”),我看到它有点打印垃圾。它打印了很多1,然后是2,然后是3,直到8,然后是:
8
8
8
8
8
10
10
10
10
1100
1100
1100
1100
1100
1100
10
11
11
11
11
在出错时,index为2,currentMakers.count为30。
答案 0 :(得分:0)
您可以非常轻松地重构该代码,而不需要在数组中修改GMSMarker
实例 - 这应该消除您所看到的任何线程问题:
var thisLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let marker = GMSMarker(position: thisLocation)
var calle = obj["calle"] as String
var numero = obj["numero"] as String
var colonia = obj["colonia"] as String
var direccion = "\(calle) \(numero), \(colonia)"
var horarioSemanal = obj["horario_lv"] as String
var horarioSabatino = obj["horario_s"] as String
var nombre = obj["sucursal"] as String
marker.icon = UIImage(named: tipo.lowercaseString)
marker.title = "\(tipo) - \(nombre)"
marker.appearAnimation = kGMSMarkerAnimationPop
marker.snippet = dirección
currentMarkers.append(marker)