2016-02-13 34 views
11

Tại sao Realm sử dụng try! nên thường xuyên? Có vẻ như nếu bạn chắc chắn cuộc gọi của mình sẽ không thành công thì bạn không nên thiết kế nó cho throw - không?Tại sao sử dụng Realm! trong Swift?

Dưới đây là một ví dụ, từ trang Swift trên realm.io:

// Get the default Realm 
let realm = try! Realm() 

hoặc

// Persist your data easily 
try! realm.write { 
    realm.add(myDog) 
} 

Đối với tôi điều này có nghĩa họ sẽ không bao giờ thất bại vậy tại sao có các nhà xây dựng hoặc viết() ném?

Trả lời

11

Nếu bạn đang đề cập đến các ví dụ trong Realm Swift Docs, tôi nghi ngờ try! được sử dụng tự do vì lợi ích ngắn gọn. Người dùng được đưa ra một cái nhìn tổng quan nhanh chóng và bẩn thỉu của các khái niệm cốt lõi mà không có quá nhiều chi phí về tinh thần.

Bạn có thể sẽ lỗi gặp phải tại một số thời điểm trong hành trình của bạn bằng cách sử dụng Realm. Bạn sẽ nhận thấy sau trong tài liệu, trong phần Realms > Error Handling có một ví dụ do-catch.

do { 
    let realm = try Realm() 
} catch let error as NSError { 
    // handle error 
} 

Đối với tôi, nó ngụ ý rằng các ví dụ mã từ các tài liệu không nhất thiết phải sản xuất chất lượng, và người dùng được khuyến khích sử dụng các tính năng lỗi xử lý có liên quan của Swift.

+1

Phạt cảnh cáo khi bắt đầu sẽ giúp người mới. –

+0

Có thực sự là một thực hành tốt để thích ngắn gọn hơn mã an toàn không? Tôi nghĩ là không. – the4kman

0

Từ các tài liệu Realm:

You may have noticed so far that we have initialized access to our realm variable by calling Realm(). That method returns a Realm object that maps to a file called “default.realm” under the Documents folder (iOS) or Application Support folder (OS X) of your app.

Bất cứ lúc nào bạn tương tác với các hệ thống tập tin bạn có nguy cơ gặp phải các lỗi như vấn đề quyền hoặc không đủ không gian đĩa. Thành công không chắc chắn.

Vì vậy, nếu vì bất kỳ lý do nào, Realm không thể tạo hoặc ghi vào tệp realm, các phương pháp này bạn viện dẫn thực sự sẽ ném một ngoại lệ.

9

Từ hướng dẫn Realm Swift 2.1.0 trong viết phần:

Because write transactions could potentially fail like any other disk IO operations, both Realm.write() & Realm.commitWrite() are marked as throws so you can handle and recover from failures like running out of disk space. There are no other recoverable errors. For brevity, our code samples don’t handle these errors but you certainly should in your production applications.

Nguồn: https://realm.io/docs/swift/latest/#writes

5

Con đường tôi đối phó với vấn đề này là bằng cách tạo ra một lớp DatabaseManager, xử lý các trường hợp không chắc của lĩnh vực ném một lỗi:

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

Nhờ giải pháp đó mã trông sạch hơn bất cứ khi nào tôi muốn đọc từ lĩnh vực hoặc viết thư cho db :)

DatabaseManager.write(realm: realm) { 
    let queryResult = self.realm.objects(Cookies.self).filter("cookieId == %@", cookieId) 
    let cookie = queryResult.first 
    cookie?.expirationDate = expirationDate as NSDate? 
} 
+2

Cảm ơn da-na, có vẻ như rất sạch sẽ. Tuy nhiên tôi không hiểu điều gì sẽ xảy ra nếu Realm() thất bại, cái gì sẽ trả về self.realm trong trường hợp đó ?? Cảm ơn bạn!! –

+3

Nó sẽ trở thành một vòng lặp vô hạn không may, và ứng dụng sẽ đóng băng. Vì vậy, chắc chắn có không gian để cải thiện ở đây. –

0

tôi tạo này cho đơn giản init gọi

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)") 
     } 
    } 
} 
Các vấn đề liên quan