Pourquoi Realm utilise-t-il try!
si souvent? Il semble que si vous êtes certain que votre appel n'échouera pas, vous ne devez pas le configurer comme suit: throw
- no?
Voici un exemple, tiré de la page Swift sur realm.io:
// Get the default Realm
let realm = try! Realm()
ou
// Persist your data easily
try! realm.write {
realm.add(myDog)
}
Pour moi, cela implique qu'ils n'échoueront jamais, alors pourquoi le constructeur ou write () jettent-ils?
Si vous vous référez aux exemples du domaine Swift Docs , je soupçonne que try!
est utilisé de manière libérale par souci de brièveté. L'utilisateur reçoit un aperçu rapide et sale des concepts de base sans trop de charge mentale.
Vous rencontrerez probablement des erreurs à un moment ou à un autre de votre parcours avec Realm. Vous remarquerez plus tard dans les docs, dans la section Realms> Error Handling qu'un exemple do-catch
est donné.
do {
let realm = try Realm()
} catch let error as NSError {
// handle error
}
Pour moi, cela signifie implicitement que les exemples de code fournis dans la documentation ne sont pas nécessairement de qualité production, et l'utilisateur est encouragé à utiliser les fonctionnalités de gestion des erreurs de Swift.
Du guide Realm Swift 2.1.0 dans la section Écrit:
Parce que les transactions d'écriture pourraient potentiellement échouer comme n'importe quel autre disque IO, Realm.write () et Realm.commitWrite () sont marqués comme jette afin que vous puissiez gérer et récupérer des échecs comme être à court de espace disque. Il n'y a pas d'autres erreurs récupérables. Pour être bref, notre Les exemples de code ne traitent pas ces erreurs, mais vous devriez le faire en vos applications de production.
La façon dont je traite ce problème consiste à créer une classe DatabaseManager, qui gère l'événement improbable où un royaume a généré une erreur:
public class DatabaseManager {
static var realm: Realm {
get {
do {
let realm = try Realm()
return realm
}
catch {
NSLog("Could not access database: ", error)
}
return self.realm
}
}
public static func write(realm: Realm, writeClosure: () -> ()) {
do {
try realm.write {
writeClosure()
}
} catch {
NSLog("Could not write to database: ", error)
}
}
}
Grâce à cette solution, le code est beaucoup plus propre chaque fois que je veux lire à partir du royaume ou écrire à db :)
DatabaseManager.write(realm: realm) {
let queryResult = self.realm.objects(Cookies.self).filter("cookieId == %@", cookieId)
let cookie = queryResult.first
cookie?.expirationDate = expirationDate as NSDate?
}
De la documentation du royaume:
Vous avez peut-être remarqué jusqu'à présent que nous avons initialisé l'accès à notre variable de royaume en appelant Realm (). Cette méthode renvoie un objet Realm mappé sur un fichier appelé «default.realm» dans le dossier Documents (iOS) ou le dossier Application Support (OS X) de votre application.
Chaque fois que vous interagissez avec le système de fichiers, vous risquez de rencontrer des erreurs telles que des problèmes d'autorisations ou un espace disque insuffisant. Le succès n'est pas certain.
Ainsi, si pour une raison quelconque, Realm est incapable de créer ou d’écrire dans le fichier de domaine, ces méthodes que vous citez lèveraient bien une exception.
Je crée ceci pour un simple appel init
import RealmSwift
// MARK: - RealmDB
/// RealmDB import realm in foundation, and add is format for refactoring catch
public class RealmDB {
/// Realm
public static var realm: Realm? {
do {
return try Realm()
} catch let error {
NotificationCenter.default.post(name: .logError, object: "Could not access database: \(error)")
return nil
}
}
/// Write in Realm
///
/// - Parameter writeClosure: Write Closure
public static func write(writeClosure: @escaping (_ realm: Realm) -> ()) {
do {
try self.realm?.write {
// self.realm has so can `!`
writeClosure(self.realm!)
}
} catch let error {
NotificationCenter.default.post(name: .logError, object: "Could not write database: \(error)")
}
}
}