2016-07-14 14 views
0

Ich möchte Fehler erfassen, wenn Bereich fehlschlägt zu schreiben und einen Fehler auslöst.Fehler nicht beim Speichern in Realm mit doppelten primaryKey

Ich führe einen Test, der versucht, zwei Objekte mit der gleichen Primärschlüssel (ID) zu speichern. Realm thorws RLMException aber es ist nicht gefangen.

static func save(article: Article) -> Bool { 

    do { 
     let realm = try Realm() 

     try realm.write { 
      realm.add(article) 
     } 
     return true 

    } catch { 
     print("***** ERROR *******") 
     return false 
    } 

} 

Ich führe einen Test wie unten.

func testDuplicateSave() { 

    let id = 7777 

    let a = Article() 
    a.id = id 
    RealmClient.save(a) 



    let a2 = Article() 
    a2.id = id 

    let resut = RealmClient.save(a2) 

    XCTAssertFalse(resut) 
} 

Antwort

2

Realm löst tatsächlich eine Objective-C-Ausnahme aus, wenn Sie versuchen, ein Objekt mit einem bereits vorhandenen Primärschlüssel beizubehalten.

Swifts Fehlerbehandlung fängt keine Objective-C-Ausnahmen ein. Es basiert auf einem ErrorType Rückgabe-Mechanismus, der NSError pointer-basierte APIs von Objective-C "übersetzt".

Das Werfen und Erfassen von Ausnahmen in Objective-C sollte im Allgemeinen vermieden werden, da es teurer ist. Im Gegensatz zu vielen anderen Sprachen sollte es nur in wirklich außergewöhnlichen Fällen geschehen, die Sie nicht vorhersehen können, nicht wenn Sie versuchen, eine Operation, die vorhersehbar ist, wie z. Bei E/A-Plattenoperationen mit NSFileManager.

Warum also wirft Realm eine Ausnahme, anstatt an dieser Stelle zu versagen? Wir betrachten das Fortbestehen eines Objekts mit einem bereits vorhandenen Primärschlüssel als einen Programmierfehler. Sie können selbst überprüfen, ob der Primärschlüssel bereits existiert. Aus diesem Grund überlassen wir es der Verantwortung des Entwicklers, verschiedene Arten von Ursachen für Fehler zu vermeiden.

static func save(article: Article) -> Bool { 
    // Opening a Realm fails if the file is inaccessible on the file 
    // system, it has a different schema version, it is encrypted 
    // and you don't provide matching credentials or the virtual 
    // address space is exhausted. If you don't provide explicit 
    // error handling for any of this cases at this place, then 
    // you can open the Realm by a force-try without hesitation. 
    let realm = try! Realm() 
    // Write transactions are mutually exclusive. So starting the 
    // transaction before checking whether an object with the same 
    // primary key already exists, ensures that such an object 
    // can't be concurrently created by any other thread. 
    realm.beginWrite() 
    if let _ = realm.objectForPrimaryKey(Article, article.id) { 
     // Object exists already. 
     realm.cancelWrite() 
     return false; 
    } 
    realm.add(article) 
    // Write transactions fail if it would cause the file to 
    // outgrow the virtual address space or the disk capacity. 
    // If you don't provide explicit error handling for this case 
    // at this place, then you can commit the write transaction 
    // by a force-try without hesitation. 
    try! realm.commitWrite() 
    return true 
} 
+0

Danke für die ausgezeichnete Antwort! Ich habe nur Codezeilen geschrieben, um doppelte Speicherung zu vermeiden. – Bigair