2016-08-11 1 views
1

관심 지점 목록이 있습니다. 이 포인트는 영역 데이터베이스에서로드되었습니다. 각 지점은 사용자 위치까지의 거리를 표시해야합니다.렐름의 오브젝트 목록에 오류가 있습니다 : 잘못된 스레드에서 액세스 한 영역

새로운 위치를 얻을 때마다 모든 포인트까지의 거리를 계산합니다. 고정 된 화면을 피하기 위해, 주 스레드의 테이블에 목록을 표시 한 후에 백그라운드 스레드에서 수학을 수행했습니다. 나는이 오류가 얻을 그러나

func updatedLocation(currentLocation: CLLocation) { 

    let qualityOfServiceClass = QOS_CLASS_BACKGROUND 
    let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) 
    dispatch_async(backgroundQueue, { 
     for point in self.points{ 
      let stringDistance = self.distanceToPoint(currentLocation, destination: point.coordinate) 
      point.stringDistance = stringDistance 
     } 

     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      self.tableView?.reloadData() 
     }) 
    }) 
} 

:

libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread. 

나는 그러나, 나는 백그라운드 스레드에서 영역 개체에 액세스하고 있습니다 때문에이 오류가 무엇입니까 알을, 그들은 이미 배열에로드 있습니다 그리고 나는 데이터베이스에 새로운 쿼리를 결코 만들지 않는다.. 또한, var 내가 데이터베이스에 저장하지 않은 그의 업데이 트됩니다.

어떻게 해결할 수 있을까요? 주 스레드에서 수학하는 것을 피하고 싶었습니다. 사전

답변

1

에서

덕분에 나는 당신이 다음과 같이 Array으로 영역을 Results 객체를 래핑 가정

let results = realm.objects(Point) 
self.points = Array(results) 

그러나,이 충분하지 않습니다. 배열의 각 요소는 여전히 영역과 연결되어 있으므로 다른 스레드에 액세스 할 수 없습니다.

권장 방법은 영역을 다시 만들고 각 스레드의 결과를 다시 가져 오는 것입니다.

dispatch_async(backgroundQueue, { 
    let realm = try! Realm() 
    let points = realm.objects(...) 

    try! realm.write { 
     for point in points{ 
      let stringDistance = self.distanceToPoint(currentLocation, destination: point.coordinate) 
      point.stringDistance = stringDistance 
     } 
    } 

    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     ... 
    }) 
}) 

영역 개체에는 실시간 업데이트 기능이 있습니다. 하위 스레드에서 영역 객체로 커밋 된 변경 사항은 다른 스레드의 객체에 즉시 반영됩니다. 따라서 주 스레드에서 쿼리를 다시 가져올 필요가 없습니다. 테이블 뷰를 다시로드하면됩니다. 당신이 배열을 포장하고 직접 다른 스레드에 전달하려는 경우 다음과 같이

, 당신은 resutls의 모든 요소를 ​​포장한다 : 응답 @kishikawa의 카츠미에 대한

let results = realm.objects(Point) 
self.points = results.map { (point) -> Point in 
    return Point(value: point) 
} 
+0

감사합니다. 나는 두 번째 접근법을 선택할 것이라고 생각한다. 이후 데이터베이스에 stringDistance를 저장하지 않아도되므로 항상 영역에 쓰는 것이 더 낫습니다. 감사 – DaSilva

관련 문제