2016-06-27 5 views
0

Я новичок в Realm и получаю ошибку «Realm accessed from wrong thread». Я прочитал, что нужно получить доступ к данным в той же области, из которой он был извлечен. Однако я получаю эту ошибку после успешного доступа к объекту. Вот код:Realm - Realm Доступен из-за неправильной темы Swift

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

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

Этот метод вызывает метод, создать массив приложений с помощью: let array = Array(results)

Я тогда проходящее это метод, который задает массив:

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

    print(applications) 
} 

В вышеописанном методе я распечатываю массив, и это работает нормально. Однако позже в цикле вызывается метод 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 
} 

Как вы можете видеть, я добавил заявление печати в указанном выше методе. Когда я пытаюсь распечатать массив приложений здесь, я получаю сбой.

Как я могу распечатать его в методе, который его устанавливает, но здесь он разбивает его? Это потому, что cellForRowAtIndexPath вызывается в основном потоке? И если да, то как я могу обновить мой tableView в этом случае? Приветствия.

========

Edit:

Когда я следующий в cellForRowAtIndexPath я вернусь пустой результат:

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

Edit 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() 
     } 

данных не всегда.

Edit 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

READ * тщательно * какой 'https: // область .io/docs/swift/latest/# threading' говорит о «нескольких потоках». –

+0

Привет, Майк, прочитав документацию, я попробовал код в своем предыдущем редактировании, где создаю новую область с: let realm = try! Realm(), а затем используйте это, чтобы попытаться восстановить мои объекты. Но результат пуст. Я перечитал раздел, который вы отправили, и я до сих пор не уверен, как я могу получить объекты. Я все еще понимаю это как: пусть realm = try! Realm(). Я что-то упускаю? – pls

+0

Используя контрольную точку исключения, вы можете увидеть, какая строка вашего кода вызывает исключение, которое Realm выбрасывает в ответ на нарушение его ограничений на потоки. Это должно точно определить объект, к которому обращаются из неправильного потока. Затем вы можете посмотреть, какой поток этот объект создается, и какой поток вы пытаетесь получить к нему доступ. – bdash

ответ

0

Edit:

Пожалуйста, прочтите комментарий от bdash ниже. Хотя это работает, это на самом деле только случайно. Оставайтесь здесь, чтобы другие не пытались сделать то же самое.

следующий код работал, но это не правильно !!!:

Так мне удалось получить его работу. Сначала я остановил приложение, и появится добавленный код, который отобразит данные. Это отлично работает. Поэтому я знал, что данные были в базе данных. Однако я хотел сохранить данные и сразу же использовать их.

Для этого мне нужно было добавить try! realm.commitWrite() внутри моего блока realm.write() { }. Полный метод ниже:

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() я был в состоянии сделать мой забрать позже в главном потоке, как так:

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

Вызов 'commitWrite()' внутри блока, переданного 'write()', неверен. Если это происходит, это происходит потому, что у вас есть проблемы в другом месте, чьи симптомы скрываются. – bdash

Смежные вопросы