设置 NSManagedObject 的 Bool 属性会引发“iOS 10 中未捕获的异常”

Posted

技术标签:

【中文标题】设置 NSManagedObject 的 Bool 属性会引发“iOS 10 中未捕获的异常”【英文标题】:Setting Bool attribute of an NSManagedObject throws "Uncaught exception in iOS 10" 【发布时间】:2016-06-24 21:32:35 【问题描述】:

我正在将我的应用升级到 ios 10 / swift 3

所以用字典(从远程数据库接收的值)构造一个NSManagedObject...

    let writerDictionary = [
        ...: writer.id,
        ...: writer.name,
        ...: writer.picture,
        ...: writer.publicationID,
        ...: writer.language,
        ...: writer.country
    ]

    let newWriter = Writer(dictionary: writerDictionary, context: SHARED_CONTEXT)

isFavorite 是一个 NSManaged 属性,我在构造 newWriter 对象之后,在保存上下文之前手动将其设置为 truenewWriter.isFavorite = true -

此行在 iOS 10 中因未捕获异常而崩溃 - 以前 iOS 9 没有任何问题

我也尝试过newWriter.setValue(true, forKey: "isFavorite") - 虽然它不会使应用程序崩溃,但布尔值isFavorite 保持不变false

有什么想法吗?这是我的 NSManagedObject 的 Writer 子类

import UIKit
import CoreData

@objc(Writer)

class Writer: NSManagedObject 

    // Attributes also in the database
    @NSManaged var id: NSNumber
    @NSManaged var name: String
    @NSManaged var picture: String?
    @NSManaged var publicationID: NSNumber
    @NSManaged var language: String
    @NSManaged var country: String
    @NSManaged var lastArticle: Date

    // Attributes only in the iOS app
    @NSManaged var isFavorite: Bool           // Initial value is false
    @NSManaged var hasNewArticles: Bool

    // Relationship objects
    @NSManaged var publication: Publication
    @NSManaged var articles: [Article]

    var writerImage: UIImage? 
        get 
            return ImageCache.sharedCache.imageWithIdentifier("writers-" + String(id))
        
        set 
            ImageCache.sharedCache.storeImage(newValue, withIdentifier: "writers-" + String(id))
        
    

    override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) 
        super.init(entity: entity, insertInto: context)
    

    init(dictionary: [String : AnyObject], context: NSManagedObjectContext) 
        let entity = NSEntityDescription.entity(forEntityName: "Writer", in: context)!
        super.init(entity: entity, insertInto: context)

        id = ...  
        name = ...  
        picture = ...  
        publicationID = ...  
        language = ...  
        country = ...  
        lastArticle = ...  
    

    override func prepareForDeletion() 
        if let _ = writerImage 
            writerImage = nil
        
    

【问题讨论】:

“未捕获的异常”不是崩溃原因。异常详情是什么? 没什么!这就是我在控制台中得到的全部内容。 “libc++abi.dylib:以 NSException 类型的未捕获异常终止” 在异常上设置断点,看看它在哪里崩溃。 当我尝试在newWriter.isFavorite = true 中将isFavorite 属性设置为true 并且控制台除了上面的双引号之间的行之外没有给出任何内容时,它会崩溃。 转到堆栈跟踪中的最后一行(在左侧),并在调试器中键入“po $arg1” 【参考方案1】:

解决方案

当前版本的 Swift 3 beta 在处理带有“is”前缀的属性方面似乎存在一些缺陷。

这样调整属性名,解决了……

 @NSManaged @objc(isFavorite) var isFavorite: Bool

【讨论】:

该死,这是我的 var 的问题,这是数据...原始 @NSManaged var jsonData: NSData 工作 @NSManaged @objc(jsonData) var jsonData: NSData【参考方案2】:

已在 Xcode 8 beta 3 编译器中修复。

来自发行说明:

早期的 Swift 3 beta 隐式重命名了属性、getter 和 名称以开头的 Bool 类型的 @objc 属性的 setter “is”,以匹配 Objective-C 命名约定。 (例如,一个 名为 isMagical 的 Swift 布尔属性生成了一个 Objective-C @property (nonatomic, getter=isMagical) BOOL 形式的声明 神奇。)事实证明,这造成的麻烦超过了它的价值,而且 已被删除。 (26847223)

【讨论】:

以上是关于设置 NSManagedObject 的 Bool 属性会引发“iOS 10 中未捕获的异常”的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject 的描述显示值,但访问它们显示 NaN?

如何在单个托管对象上下文中初始化新的 NSManagedObject 并设置与另一个 NSManagedObject 的关系?

NSManagedObject - 跨线程设置自定义实例变量

类别中的自定义 NSManagedObject 设置器

为啥我的 ivar 没有在 NSManagedObject 子类上设置

NSManagedObject 子类中的自定义设置器