2015-07-03 83 views
3

對於這個問題的緣故內的對象,這裏有一個簡單的例子(有幾個快捷鍵):境界斯威夫特:更新封閉

class Foo: Object { 
    dynamic var id: Int = 0 
    [...] 
} 

class Bar: Object { 
    dynamic var id: Int = 0 
    dynamic var foo: Foo? 

    convenience required init(data: AnyObject) { 
    self.init() 
    self.id = data.id as! Int 

    if let foo_id = data.foo_id as? Int { 
     // Function querying the remote database and returning an object 
     Foo.get(foo_id) { (foo) -> Void in 
     self.foo = foo // Foo object assigned, as expected 
     } 
    } 
    } 
} 

如果我在get()關閉做self.foo = foo函數,我得到一個例外:

異常'RLMException',原因:'嘗試修改寫事務之外的對象 - 首先在RLMRealm實例上調用beginWriteTransaction。

所以,如果我加入它周圍的realm.write,如要求由前一個異常:

... 
Foo.get(foo_id) { (foo) -> Void in 
    let realm = Realm(path: Realm.defaultPath) 
    realm.write { 
    self.foo = foo 
    } 
} 
... 

這一次,我得到一個新問題:

異常「RLMException ',原因:'不能添加對象從一個不同的領域'

我卡住了,我不明白什麼是領域是想g來自我這裏,文檔沒有幫助。

我並不習慣於領域,所以我想我的工作方式有問題,但我不知道是什麼。

感謝您的幫助

+0

您是否正在對已經保存在* ANY *其他領域的對象執行此操作? 「Realm.defaultPath」以外的東西?第一個異常很明顯 - 要麼執行'beginWriteTransaction()' - > write - >'commitWriteTransaction()'或者你提到的那個塊。另一個異常發生在您嘗試更新**錯誤**領域中的對象時,而不是您已將其保存到的對象。 – Michal

+0

我只有一個領域,我使用默認的。我想這可能與對象初始化後在閉包中使用'self'有關? – Sylver

+0

我也嘗試過'self.realm.write(){...}',但'self.realm'是可選的,在嘗試寫入我的對象時爲零,所以我看不到使用這個的一點 – Sylver

回答

4

OK,所以這個問題是這樣的 - 你想打開的時候對象不保存在初始化本身境界write()會議上,我的猜測是,該框架是不是真的對此感到高興。

我的做法的建議是這樣的:

  1. 設置你的對象從數據庫獲取數據之前知道的價值觀和你沒有任何設置一些默認值,其餘或設置他們作爲可選值。
  2. 將對象保存到域中,然後在閉包中調用下載(當然是異步的) - 這會將對象放在閉包中,因爲那時對象將被保存在域中,您將可以直接訪問savedObject.realm,你將能夠正常寫入,無一例外。
+1

我提高了你的答案,因爲它是正確的,但我不完全同意你的建議。我發佈了另一個應該以不同視角提供OP的答案。謝謝回答! – jpsim

1

tl; dr;您不能將持久化的Realm對象分配給未被執行的Realm對象的屬性

瞭解Foo.get(_:)正在做什麼會很有用。我的猜測是,它會創建一個持久化的Realm對象(可能甚至在不同的線程上),而對象永遠不會持久化(調用super.init()只會創建一個獨立的對象,而不會與任何Realm鏈接)。

如果我對Foo.get(_:)的假設是正確的,只需在該函數中創建一個獨立的Foo。然後,您可以在任何寫入交易之外將其設置爲Bar的財產。