2014-11-28 5 views
1

이상한 오류가 발생했습니다. 배열에 항목을 추가 한 다음 .last 속성을 통해 해당 항목에 액세스하지만 임의로 "치명적인 오류 : 배열 색인이 범위를 벗어났습니다."라는 메시지가 나타납니다.iOS Swift : 마지막 속성에 액세스 할 때 배열 인덱스가 범위를 벗어납니다.

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 

오류 임의로 마지막 네 개의 라인 중 하나에 보여

여기 (for 루프 내부) 내 코드이다. 나는 또한 다음과 같은 방법으로 액세스를 시도했습니다.

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)을 사용하고 있습니다.

희망을 미리 보내 주시면 감사하겠습니다.

편집 : 네이트의 답변을 구현

이 지금 오류가 다른 라인으로 이동, 여기 내 함수의 시작이다 :

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 & & 경도 == currentMarkers [index] .position.longitude {행 또는 if currentMarkers [index] .title.rangeOfString ("cajero")! = nil {line.

for 루프를 시작한 직후에 println ("(currentMakers.count)")을 추가했는데 인쇄 가비지가 표시됩니다. 그것은 8까지, 다음 다음 1, 2, 3을 많이 인쇄 한 다음 : 오류의 순간

8 
8 
8 
8 
8 
10 
10 
10 
10 
1100 

1100 

1100 

1100 

1100 

1100 

10 
11 
11 
11 
11 

, 지수는 2이고 currentMakers.count는 30

답변

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) 
+0

덕분에 많이. 구현했지만 오류가 다른 행 집합으로 바뀌 었습니다. 응답 코드에 코드를 붙여 넣는 방법을 잘 모르겠습니다. 그래서 제 질문을 수정하겠습니다. –