Tôi đã có một ứng dụng được phát hành bằng cách sử dụng Realm và có một số nhật ký sự cố cho thấy đôi khi không tạo được cõi bằng cấu hình dẫn đến lỗi EXC_BREAKPOINT (SIGTRAP). (Có 9 file crash cho một vài trăm cài đặt ứng dụng để không phải cái gì của nó mà đang xảy ra thường xuyên)Điều gì có thể là nguyên nhân gây ra lỗi không thường xuyên khi tạo đối tượng Realm được mã hóa?
@objc class Database : NSObject
{
let configuration = Realm.Configuration(encryptionKey: Database.getKey() as Data)
var transactionRealm:Realm? = nil
override init()
{
let realm = try! Realm(configuration: configuration) // Crash here
<snip>
}
// This getKey() method is taken from the Realm website
class func getKey() -> NSData {
let keychainIdentifier = "Realm.EncryptionKey.AppKey"
let keychainIdentifierData = keychainIdentifier.data(using: String.Encoding.utf8, allowLossyConversion: false)!
// First check in the keychain for an existing key
var query: [NSString: AnyObject] = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecReturnData: true as AnyObject
]
// To avoid Swift optimization bug, should use withUnsafeMutablePointer() function to retrieve the keychain item
// See also: http://stackoverflow.com/questions/24145838/querying-ios-keychain-using-swift/27721328#27721328
var dataTypeRef: AnyObject?
var status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }
if status == errSecSuccess {
return dataTypeRef as! NSData
}
// No pre-existing key from this application, so generate a new one
let keyData = NSMutableData(length: 64)!
let result = SecRandomCopyBytes(kSecRandomDefault, 64, keyData.mutableBytes.bindMemory(to: UInt8.self, capacity: 64))
assert(result == 0, "REALM - Failed to get random bytes")
// Store the key in the keychain
query = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecValueData: keyData,
kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
]
status = SecItemAdd(query as CFDictionary, nil)
assert(status == errSecSuccess, "REALM - Failed to insert the new key in the keychain")
return keyData
}
Dưới đây là phần có liên quan của tập tin vụ tai nạn:
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000103c0f30c
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [0]
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 libswiftCore.dylib 0x0000000103c0f30c 0x103ab4000 + 1422092
1 libswiftCore.dylib 0x0000000103c0f30c 0x103ab4000 + 1422092
2 libswiftCore.dylib 0x0000000103b13d2c 0x103ab4000 + 392492
3 libswiftCore.dylib 0x0000000103b13bf4 0x103ab4000 + 392180
4 My app 0x000000010334ff14 _TFC14Caller_Name_ID8DatabasecfT_S0_ + 1648 (Database.swift:21)
5 My app 0x0000000103330624 -[Model createDatabase] + 200 (Model.m:271)
dòng 21 của Database.swift tệp là tệp được chỉ ra trong mã ở trên trong phương thức Init().
Nếu lý do cho sự cố Realm là do getKey() không thành công thì tại sao điều đó lại thất bại? Nếu đó không phải là nguyên nhân, thì những lý do khác cho sự thất bại là gì? Và có bất cứ điều gì mã có thể làm (chẳng hạn như thử lại để tạo đối tượng Realm) nếu có sự cố không?
Cảm ơn bạn đã dành thời gian trả lời. – Gruntcakes