仅在应用首次启动时才会出现此问题。使用NSInMemoryStoreType
时出现 NOT 问题。
iOS内部处理异常并且不会导致应用程序崩溃,但我认为最好在可能的情况下将其删除。
* thread #1, queue = 'SQLQueue 0x7fb663441f20 for MyApp.sqlite', stop reason = breakpoint 1.1
* frame #0: 0x000000010e45c001 libobjc.A.dylib`objc_exception_throw
frame #1: 0x000000010df2ed1e Foundation`-[NSCoder(Exceptions) __failWithException:] + 136
frame #2: 0x000000010df2ee9b Foundation`-[NSCoder(Exceptions) __failWithExceptionName:errorCode:format:] + 381
frame #3: 0x000000010de81b26 Foundation`-[NSCoder validateClassSupportsSecureCoding:] + 326
frame #4: 0x000000010dea52d0 Foundation`_encodeObject + 397
frame #5: 0x000000010df57798 Foundation`+[NSKeyedArchiver(NSKeyedArchiverSecureCodingInitializers) archivedDataWithRootObject:requiringSecureCoding:error:] + 102
frame #6: 0x00000001119a23a1 CoreData`-[NSSQLiteConnection _compressedDataWithModel:] + 65
frame #7: 0x00000001119a262b CoreData`-[NSSQLiteConnection saveCachedModel:] + 251
frame #8: 0x00000001119a32e7 CoreData`-[NSSQLiteConnection createSchema] + 391
frame #9: 0x000000011184262a CoreData`-[NSSQLiteConnection connect] + 2170
frame #10: 0x0000000111965dce CoreData`__32-[NSSQLCore _loadAndSetMetadata]_block_invoke + 158
frame #11: 0x000000011199935e CoreData`__37-[NSSQLiteConnection performAndWait:]_block_invoke + 30
frame #12: 0x0000000113809848 libdispatch.dylib`_dispatch_client_callout + 8
frame #13: 0x00000001138105b8 libdispatch.dylib`_dispatch_queue_barrier_sync_invoke_and_complete + 374
frame #14: 0x000000011199928f CoreData`-[NSSQLiteConnection performAndWait:] + 159
frame #15: 0x0000000111841516 CoreData`-[NSSQLCore _loadAndSetMetadata] + 326
frame #16: 0x0000000111841274 CoreData`-[NSSQLCore loadMetadata:] + 148
frame #17: 0x0000000111949184 CoreData`__91-[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:]_block_invoke + 1988
引发异常的原因是什么?
是NSManagedObjectModel
代码(没有xcdatamodeld
文件)会导致麻烦吗?
更新1 :
NSManagedObjectModel
代码:
public class ManagedObjectModel: NSManagedObjectModel {
public override init() {
super.init()
entities.append(makeFriendEntity())
entities.append(makeProfileEntity())
entities.append(makePostEntity())
}
public required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
extension ManagedObjectModel {
private func makeFriendEntity() -> NSEntityDescription {
let attributeUserName = NSAttributeDescription()
attributeUserName.name = #keyPath(FriendEntity.userName)
attributeUserName.attributeType = .stringAttributeType
attributeUserName.isOptional = false
let attributeAvatarPictureURL = NSAttributeDescription()
attributeAvatarPictureURL.name = #keyPath(FriendEntity.avatarPictureURL)
attributeAvatarPictureURL.attributeType = .URIAttributeType
attributeAvatarPictureURL.isOptional = false
let attributeAvatarPictureIsSilhouette = NSAttributeDescription()
attributeAvatarPictureIsSilhouette.name = #keyPath(FriendEntity.avatarPictureIsSilhouette)
attributeAvatarPictureIsSilhouette.attributeType = .booleanAttributeType
attributeAvatarPictureIsSilhouette.isOptional = false
attributeAvatarPictureIsSilhouette.defaultValue = true
let attributeAvatarPictureData = NSAttributeDescription()
attributeAvatarPictureData.name = #keyPath(FriendEntity.avatarPictureData)
attributeAvatarPictureData.attributeType = .binaryDataAttributeType
attributeAvatarPictureData.isOptional = true
attributeAvatarPictureData.allowsExternalBinaryDataStorage = true
let indexDescription = NSFetchIndexElementDescription(property: attributeUserName, collationType: .binary)
indexDescription.isAscending = true
let index = NSFetchIndexDescription(name: "com_mc_index_friend_userName", elements: [indexDescription])
let entity = NSEntityDescription()
entity.name = FriendEntity.entityName
entity.managedObjectClassName = FriendEntity.entityClassName
entity.properties = [attributeUserName, attributeAvatarPictureURL,
attributeAvatarPictureIsSilhouette, attributeAvatarPictureData]
entity.renamingIdentifier = "com.mc.entity-friend"
entity.indexes = [index]
return entity
}
private func makeProfileEntity() -> NSEntityDescription {
let attributeUserName = NSAttributeDescription()
attributeUserName.name = #keyPath(ProfileEntity.userName)
attributeUserName.attributeType = .stringAttributeType
attributeUserName.isOptional = false
let attributeHomeTown = NSAttributeDescription()
attributeHomeTown.name = #keyPath(ProfileEntity.homeTown)
attributeHomeTown.attributeType = .stringAttributeType
attributeHomeTown.isOptional = true
let attributeCoverPhotoData = NSAttributeDescription()
attributeCoverPhotoData.name = #keyPath(ProfileEntity.coverPhotoData)
attributeCoverPhotoData.attributeType = .binaryDataAttributeType
attributeCoverPhotoData.isOptional = true
attributeCoverPhotoData.allowsExternalBinaryDataStorage = true
let attributeAvatarPictureData = NSAttributeDescription()
attributeAvatarPictureData.name = #keyPath(ProfileEntity.avatarPictureData)
attributeAvatarPictureData.attributeType = .binaryDataAttributeType
attributeAvatarPictureData.isOptional = true
attributeAvatarPictureData.allowsExternalBinaryDataStorage = true
let indexDescription = NSFetchIndexElementDescription(property: attributeUserName, collationType: .binary)
indexDescription.isAscending = true
let index = NSFetchIndexDescription(name: "com_mc_index_profile_userName", elements: [indexDescription])
let entity = NSEntityDescription()
entity.name = ProfileEntity.entityName
entity.managedObjectClassName = ProfileEntity.entityClassName
entity.properties = [attributeUserName, attributeHomeTown, attributeCoverPhotoData, attributeAvatarPictureData]
entity.renamingIdentifier = "com.mc.entity-profile"
entity.indexes = [index]
return entity
}
private func makePostEntity() -> NSEntityDescription {
let attributeCreatedDate = NSAttributeDescription()
attributeCreatedDate.name = #keyPath(PostEntity.createdDate)
attributeCreatedDate.attributeType = .dateAttributeType
attributeCreatedDate.isOptional = false
let attributeDescription = NSAttributeDescription()
attributeDescription.name = #keyPath(PostEntity.desc)
attributeDescription.attributeType = .stringAttributeType
attributeDescription.isOptional = true
let attributeID = NSAttributeDescription()
attributeID.name = #keyPath(PostEntity.id)
attributeID.attributeType = .stringAttributeType
attributeID.isOptional = false
let attributeType = NSAttributeDescription()
attributeType.name = #keyPath(PostEntity.type)
attributeType.attributeType = .stringAttributeType
attributeType.isOptional = false
let attributeTitle = NSAttributeDescription()
attributeTitle.name = #keyPath(PostEntity.title)
attributeTitle.attributeType = .stringAttributeType
attributeTitle.isOptional = true
let attributeSubtitle = NSAttributeDescription()
attributeSubtitle.name = #keyPath(PostEntity.subtitle)
attributeSubtitle.attributeType = .stringAttributeType
attributeSubtitle.isOptional = true
let attributePictureData = NSAttributeDescription()
attributePictureData.name = #keyPath(PostEntity.pictureData)
attributePictureData.attributeType = .binaryDataAttributeType
attributePictureData.isOptional = true
attributePictureData.allowsExternalBinaryDataStorage = true
let attributePictureURL = NSAttributeDescription()
attributePictureURL.name = #keyPath(PostEntity.pictureURL)
attributePictureURL.attributeType = .URIAttributeType
attributePictureURL.isOptional = true
let attributeVideoURL = NSAttributeDescription()
attributeVideoURL.name = #keyPath(PostEntity.videoURL)
attributeVideoURL.attributeType = .URIAttributeType
attributeVideoURL.isOptional = true
let indexDescription1 = NSFetchIndexElementDescription(property: attributeCreatedDate, collationType: .binary)
indexDescription1.isAscending = true
let index1 = NSFetchIndexDescription(name: "com_mc_index_post_createdDate", elements: [indexDescription1])
let indexDescription2 = NSFetchIndexElementDescription(property: attributeID, collationType: .binary)
indexDescription2.isAscending = true
let index2 = NSFetchIndexDescription(name: "com_mc_index_post_id", elements: [indexDescription2])
let entity = NSEntityDescription()
entity.name = PostEntity.entityName
entity.managedObjectClassName = PostEntity.entityClassName
entity.properties = [attributeCreatedDate, attributeDescription, attributeID, attributeVideoURL,
attributePictureData, attributePictureURL, attributeType, attributeTitle, attributeSubtitle]
entity.renamingIdentifier = "com.mc.entity-post"
entity.indexes = [index1, index2]
return entity
}
}
更新2:
似乎从代码创建NSManagedObjectModel
的正确方法 - 创建没有子类化。
public class ManagedObjectModel {
public static func makeModel() -> NSManagedObjectModel {
let model = NSManagedObjectModel() // No need to make subclass. Just assign `entities` property.
model.entities = [makeFriendEntity(),
makeProfileEntity(),
makePostEntity()]
return model
}
...
}