2016-11-01 72 views
0

我從Object這個類繼承:對象已被刪除或無效的境界

class Location: Object { 
    dynamic var id: String = "" 
    dynamic var name: String = "" 

    override class func primaryKey() -> String { 
     return "id" 
    } 
} 

這個類被用作一個實例,我的經理裏面是這樣的:

class LocationServiceAPI { 

    fileprivate var _location: Location? 
    var location: Location? { 
     get { 
      if _location == nil { 
       let realm = try! Realm() 
       _location = realm.objects(Location.self).first 
      } 
      return _location 
     } 
     set { 
      let realm = try! Realm() 

      if let newValue = newValue { 
       // delete previous locations 
       let locations = realm.objects(Location.self) 
       try! realm.write { 
        realm.delete(locations) 
       } 

       // store new location 
       try! realm.write { 
        realm.add(newValue, update: true) 
        _location = newValue 
       } 
      } else { 
       let locations = realm.objects(Location.self) 
       try! realm.write { 
        realm.delete(locations) 
       } 
      } 
     } 
    } 
} 

所以每當我得到一個位置我刪除舊的(新舊位置可能相同)並將其替換爲新的,然後我使用newValue作爲屬性_location的新值,但每當我嘗試訪問location時,它都會給我'Object has已被刪除或無效「。

我真的很困惑,因爲location將持有從setter傳遞的值,但不是領域!

注意:如果我停止刪除,那麼它會正常工作。

+0

如何刪除丟棄的位置?第二個問題:你使用線程嗎? –

+0

@bogdanf我用刪除部分更新了我的答案。 –

+0

因此,您只需在整個應用程序中使用一個'Location'對象(刪除數據庫中的所有'Location'對象,因此我假設您只有一個)。爲什麼不將它存儲在NSUserDefaults中,實際上不需要數據庫來存儲一個對象:-) 現在,如果您絕對需要將它保存在Realm中,只需從數據庫直接保存/檢索它即可我已經在我的回覆中向您展示了,真的沒有必要將它緩存到LocationServicesAPI類中的變量中。 –

回答

0

如果某個對象已從Realm中刪除,但您隨後嘗試訪問該代碼在刪除之前掛起的該對象實例的存儲屬性,則會出現Object has been deleted or invalidated錯誤。

您需要檢查自己的邏輯路徑,並確保不會刪除位置對象,也不會隨後更新_location屬性。沒有提及刪除您提供的示例代碼中的對象,但是您的if let newValue = newValue代碼行意味着如果您通過nil_location實際上不會被清除。

最後,可以通過調用_location.invalidated來手動檢查某個對象是否已從Realm中刪除,因此如果發生這種情況很多,在代碼中包含一些額外的檢查可能是一個好主意。

+0

我已經用刪除部分更新了我的答案。 –

0

不知道關於您的應用程序和您的設計選擇的任何事情,它看起來像試圖通過緩存位置屬性來避免太頻繁地讀取/寫入數據庫。除非你有噸LocationServiceAPI對象的工作不應該是一個真正的性能損失實際讀取/直接在DB寫,就像這樣:

class LocationServiceAPI { 

    var location: Location? { 
     get { 
      let realm = try! Realm() 
      return realm.objects(Location.self).first 
     } 
     set { 
      let realm = try! Realm() 
      if let newValue = newValue { 
       // store new location 
       try! realm.write { 
        realm.add(newValue, update: true) 
       } 
      } else { 
       // delete the record from Realm 
       ... 
      } 
     } 
    } 
} 

此外,我一般避免將沿着境界對象對於更長的時間段,我不認爲這是不可能的,但總的來說,它會導致像你經歷過的問題(特別是如果是多線程)。在大多數情況下,我寧願從DB獲取對象,使用它,將其更改並儘快保存在數據庫中。如果需要保留對數據庫中特定記錄的引用,我寧願保留該id,並在需要時重新獲取它。

相關問題