2016-06-27 2 views
0

저는 Realm을 처음 사용하고 '틀린 스레드에서 액세스 한 영역'오류가 발생했습니다. 나는 그것이 검색된 동일한 영역의 데이터에 액세스해야한다는 것을 읽었습니다. 그러나 성공적으로 개체에 액세스 할 수있게 된 후이 오류가 나타납니다. let array = Array(results)영역 - 틀린 스레드에서 액세스 한 영역 스위프트

그때 배열 설정하는 방법이를 전달하고있다 :

func setApplicationItems(items: [Application]) { 
    applications = items 

    print(applications) 
} 

func retrieveApplicationData(completionBlock: (Results<Application>, NSError?) -> Void) { 
     let realm = try! Realm() 
     let applications = realm.objects(Application) 

     if applications.count > 0 { 
      completionBlock(applications, nil) 
     } 
} 

이 방법을 사용하여 응용 프로그램의 배열을 생성하는 방법을 호출 여기에 몇 가지 코드입니다

위의 방법에서는 배열을 인쇄하고 잘 작동합니다. 그러나 나중에주기에서 tableViewDatasource 메서드 cellForRowAtIndexPath가 호출됩니다. 여기에서는 응용 프로그램 배열을 사용하려고하는데 응용 프로그램이 '잘못된 스레드'오류로 인해 충돌합니다. 방법은 다음과 같습니다.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    print("\(applications)") 

    let cell = ApplicationTableViewCell(style: .Subtitle, reuseIdentifier: nil) 
    let application = applications[indexPath.row] 
    cell.configureCell(application) 

    return cell 
} 

위에서 보았 듯이 위의 방법으로 print 문을 추가했습니다. 내가 여기서 응용 프로그램 배열을 인쇄하려고하면 충돌이 발생합니다.

어떻게 설정하고있는 방법으로 인쇄 할 수 있습니까?하지만 여기에 문제가 있습니다. 메인 스레드에서 cellForRowAtIndexPath이 호출 되었기 때문입니까? 그렇다면이 경우 내 tableView을 어떻게 업데이트 할 수 있습니까? 건배.

========

편집 :

나는 cellForRowAtIndexPath에서 다음을 수행 내가 다시 빈 결과 얻을 :

let realm = try! Realm() 
let applicationsB = realm.objects(Application) 

편집 2 :

폐쇄 처리시 저장 작업을 처리합니다. 데이터를 반환했을 때 여전히 크래시가 발생했을 때 dispatch_async을 사용하여 주 스레드로 다시 전달하려고했습니다. 그러나 나는이 dispatch_async을 self.tableView.reloadData()를 호출하기 바로 전에 이동했습니다. 지금은 좋지는 않지만 데이터가 항상 유효하지는 않습니다. 중단 점을 사용하여 속도를 늦추면 데이터가 다시 반환됩니다. 그러나 데이터를 그냥 놓아두면 데이터가 없습니다. 백그라운드 스레드에 저장된 데이터가 메인 스레드에서 언제 사용 가능한지를 알 수있는 방법이 있습니까? 여기

내가 사용하고있는 코드입니다 :

dispatch_async(dispatch_get_main_queue()) {    
      let realm = try! Realm() 
      realm.refresh() 
      let applicationsB = realm.objects(Application) 
      let array = Array(applicationsB) 
      self.tableViewDataSource.setApplicationItems(array as! [Application]) 
      self.tableView.reloadData() 
     } 

데이터가 항상 없다.

편집 3 :

나는 지금 dispath_async(dispath_get_main_queue())의 저장 방법을 포장하고 그것을 잘 작동합니다 :

dispatch_async(dispatch_get_main_queue()) { 

      let realm = try! Realm() 
      try! realm.write() { 

      let applications = data.map({ (object) -> Application in 
       return Application(applicationID: object.applicationID, contact: "", state: "", jobBoard: object.jobBoard, salary: object.salary, title: object.title, location: "") 
      }) 

      for application in applications { 
       print(application) 
       realm.add(application) 
      } 

      //try! realm.commitWrite() 

      completionBlock(true, nil) 

     } 
+0

읽기 *주의 * 어떤'은 https : // 영역을

try realm.write() { let applications = data.map({ (object) -> Application in return Application(applicationID: object.applicationID, contact: "", state: "", jobBoard: object.jobBoard, salary: object.salary, title: object.title, location: "") }) for application in applications { print(application) realm.add(application) } try! realm.commitWrite() // *NOTE* Here is the code I added. completionBlock(true, nil) } 

나는() 나는과 같이 주 스레드에서 나중에 가져 오기 내 할 수 있었다 commitWrite을 추가하면 .io/docs/swift/latest/# threading'은 "multiple threads"에 대해 말합니다. –

+0

안녕하세요 마이크, 설명서를 읽은 후 이전 편집에서 코드를 사용하여 새로운 영역을 만들었습니다 : letm = try! Realm()을 사용하여 내 객체를 시도하고 검색합니다. 그러나 결과는 비어 있습니다. 내가 보낸 섹션을 다시 읽었는데 여전히 어떻게 개체를 검색 할 것인지 확신 할 수 없습니다. 나는 아직도 그것을 이해한다 : 영역 = 시도하자! 왕국(). 내가 놓친 게 있니? – pls

+0

예외 브레이크 포인트를 사용하면 스레드의 제한 조건을 위반 한 Realm이 예외를 트리거하는 코드 행을 확인할 수 있습니다. 그것은 잘못된 스레드에서 액세스되는 객체를 찾아야합니다. 그런 다음 해당 객체가 어떤 쓰레드인지, 어떤 쓰레드인지를 볼 수 있습니다. – bdash

답변

0

편집 :

아래 bdash에서 코멘트를 읽어 보시기 바랍니다. 이 방법이 효과적 일지는 모르지만 실제로는 우연히 만 가능합니다. 다른 사람들이 똑같은 것을 시도하지 않도록 여기에서 답을 남깁니다.

다음 코드는 작동하지만 올바르지 않습니다! :

그래서 나는 그것이 작동 얻을 관리했다. 먼저 앱을 중지하고 데이터를 가져온 뷰에 코드를 추가했습니다. 이것은 잘 동작했다. 그래서 데이터가 데이터베이스에 있다는 것을 알았습니다. 그러나 나는 데이터를 저장하고 즉시 사용하고 싶었다.

이 작업을 수행하려면 내 realm.write() { } 블록 안에 다음을 추가해야했습니다. try! realm.commitWrite(). 아래 전체 방법 :

dispatch_async(dispatch_get_main_queue()) { 

      let realm = try! Realm() 
      realm.refresh() 
      let applicationsB = realm.objects(Application) 
      let array = Array(applicationsB) 

      self.tableViewDataSource.setApplicationItems(array as! [Application]) 


      self.tableView.reloadData() 
     } 
+1

'write()'에 전달 된 블록 내에서'commitWrite()'를 호출하는 것이 올바르지 않습니다. 일이 생기면 다른 곳에서 문제가있어이 증상이 애매 해지기 때문입니다. – bdash