核心数据中的 NSSecureCoding 崩溃
NSSecureCoding crash in Core Data
当我使用获取请求从我的核心数据实体获取时,我收到了用户的崩溃报告。这是崩溃的样子:
SIGABRT: Unhandled error (NSCocoaErrorDomain, 4864) occurred during
faulting and was thrown: Error Domain=NSCocoaErrorDomain Code=4864
"The data couldn’t be read because it isn’t in the correct format."
UserInfo={NSUnderlyingError=0x2822582d0 {Error
Domain=NSCocoaErrorDomain Code=4864 "value for key 'NS.objects' was of
unexpected class 'NSTextAlternatives (0x1ffa90890)
[/System/Library/PrivateFrameworks/UIFoundation.framework]'. Allowed
classes are '{( "NSTextAttachment (0x1ff3bc730)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSNumber
(0x1ff35d8c8) [/System/Library/Frameworks/Foundation.framework]",
"NSDictionary (0x1ff352418)
[/System/Library/Frameworks/CoreFoundation.framework]", "NSFont
(0x1ff3bc3e8)
[/System/Library/PrivateFrameworks/UIFoundation.framework]",
"NSGlyphInfo (0x1ffa906d8)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSArray
(0x1ff352238) [/System/Library/Frameworks/CoreFoundation.framework]",
"NSParagraphStyle (0x1ff3bbec0)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSUUID
(0x1ff35f290) [/System/Library/Frameworks/Foundation.framework]",
"NSDate (0x1ff3522b0)
[/System/Library/Frameworks/CoreFoundation.framework]", "NSColor
(0x1ff3a67a8)
[/System/Library/PrivateFrameworks/UIKitCore.framework]", "NSNull
(0x1ff3527b0) [/System/Library/Frameworks/CoreFoundation.framework]",
"NSData (0x1ff3519c8)
[/System/Library/Frameworks/CoreFoundation.framework]", "UIColor
(0x1ff3a6a78)
[/System/Library/PrivateFrameworks/UIKitCore.framework]",
"NSAttributedString (0x1ff359c00)
[/System/Library/Frameworks/Foundation.framework]", "NSURL
(0x1ff352e18) [/System/Library/Frameworks/CoreFoundation.framework]",
"NSSet (0x1ff352878)
[/System/Library/Frameworks/CoreFoundation.framework]", "NSValue
(0x1ff35d940) [/System/Library/Frameworks/Foundation.framework]",
"UIFont (0x1ff3bc780)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSString
(0x1ff35d170) [/System/Library/Frameworks/Foundation.framework]" )}'."
UserInfo={NSDebugDescription=value for key 'NS.objects' was of
unexpected class 'NSTextAlternatives (0x1ffa90890)
[/System/Library/PrivateFrameworks/UIFoundation.framework]'. Allowed
classes are '{( "NSTextAttachment (0x1ff3bc730)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSNumber
(0x1ff35d8c8) [/System/Library/Frameworks/Foundation.framework]",
"NSDictionary (0x1ff352418)
[/System/Library/Frameworks/CoreFoundation.framework]", "NSFont
(0x1ff3bc3e8)
[/System/Library/PrivateFrameworks/UIFoundation.framework]",
"NSGlyphInfo (0x1ffa906d8)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSArray
(0x1ff352238) [/System/Library/Frameworks/CoreFoundation.framework]",
"NSParagraphStyle (0x1ff3bbec0)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSUUID
(0x1ff35f290) [/System/Library/Frameworks/Foundation.framework]",
"NSDate (0x1ff3522b0)
[/System/Library/Frameworks/CoreFoundation.framework]", "NSColor
(0x1ff3a67a8)
[/System/Library/PrivateFrameworks/UIKitCore.framework]", "NSNull
(0x1ff3527b0) [/System/Library/Frameworks/CoreFoundation.framework]",
"NSData (0x1ff3519c8)
[/System/Library/Frameworks/CoreFoundation.framework]", "UIColor
(0x1ff3a6a78)
[/System/Library/PrivateFrameworks/UIKitCore.framework]",
"NSAttributedString (0x1ff359c00)
[/System/Library/Frameworks/Foundation.framework]", "NSURL
(0x1ff352e18) [/System/Library/Frameworks/CoreFoundation.framework]",
"NSSet (0x1ff352878)
[/System/Library/Frameworks/CoreFoundation.framework]", "NSValue
(0x1ff35d940) [/System/Library/Frameworks/Foundation.framework]",
"UIFont (0x1ff3bc780)
[/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSString
(0x1ff35d170) [/System/Library/Frameworks/Foundation.framework]"
)}'.}}}CrashVersion 5.6.8 (5.6.9)1 user1 report
当 NSFetchedResultsController
调用 performFetch
:
时崩溃的行
7 CoreData 0x00000001b48c1a94
__43-[NSFetchedResultsController performFetch:]_block_invoke + 572 8 CoreData 0x00000001b487c01c
developerSubmittedBlockToNSManagedObjectContextPerform + 152 9
CoreData 0x00000001b474eda4
-[NSManagedObjectContext performBlockAndWait:] + 204 10 CoreData 0x00000001b475cae4 -[NSFetchedResultsController
_recursivePerformBlockAndWait:withContext:] + 144 11 CoreData 0x00000001b475cc1c -[NSFetchedResultsController performFetch:] + 220
这几乎肯定会发生,因为我最近将一个没有任何转换器集的可转换属性(因此基本上使用 NSKeyedUnarchiveFromDataTransformerName
)更改为使用 NSSecureUnarchiveFromDataTransformer
的子 class .该属性正在存储来自 iOS 应用程序中的 UITextView
的 NSAttributedString
。我还将 'bold' 和 'italics' 项目的 NSRange 保存为 NSValue。
我添加了以下转换器:
@objc(AttributedStringDictionaryTransformer)
final class AttributedStringDictionaryTransformer: NSSecureUnarchiveFromDataTransformer {
override static var allowedTopLevelClasses: [AnyClass] {
return super.allowedTopLevelClasses + [NSValue.self]
}
}
这个'transformer'用于核心数据模型中的Transformable属性。它将 NSValue
class 添加到 classes.
的允许列表中
当它说“键 'NS.objects' 的值是意外的 class 'NSTextAlternatives”时......我不确定 NSTextAlternatives
是什么。我从来没有(明确地)在我的代码中使用过它。任何想法可能来自哪里?
编辑:
在进一步调查中,事实证明 NSAttributedString 可以附加各种对象,例如 NSTextAlternatives
和 _UITextInputDictationResultMetadata
的对象,如果用户在 UITextView 上使用听写,这些对象可能会出现。所以技术上支持 NSAttributedString 的 NSSecureUnarchiveFromDataTransformer
实际上并没有正确支持它。这些 classes 来自私有框架,所以不确定如何将它们添加到我的自定义转换器中。除了提交错误外,不确定是否有其他解决方法。如果有,请告诉我。
事实上,NSAttributedString
可能有点像文本系统相关属性的抓包:文本视图中的各种操作可能导致文本系统(CoreText、UIKit 等)注释范围使用一些元数据来改善 iOS 体验,但这确实意味着任何给定的 NSAttributedString
最终都会带来一些您可能没有意识到的包袱。 (从概念上讲,NSAttributedString
就像一个 NSString
和一个关联的 NSDictionary
,它可以包含 任何东西 ,如果你斜眼看的话。)文本的常规使用视图可能会导致这种情况,当您也考虑从 other 属性字符串源粘贴文本时,您最终可能会得到许多您不期望的属性值。这是按预期工作的文本系统。
不幸的是,这种设计与 NSSecureCoding
相冲突,后者要求您在解码之前列出您希望从存档中解码的类型。你正确地将 NSAttributedString
和 NSValue
对象列入白名单,并且 NSAttributedString
本身将它知道的几种类型列入白名单(并且 NSSecureUnarchiveFromDataTransformer
也允许一些已知的 Foundation 类型),但是问题是字符串最终包含 neither 你 nor NSAttributedString
知道的类型,并且如果不将这些列入白名单,解码将被阻止。
由于这些类型确实是私有的,您将很难找到文本系统可能抛给您的所有可能的私有类型。最简单的方法是在 encoding 方面:在对 NSAttributedString
进行编码之前,遍历其所有属性范围并删除类型不符合您的任何属性白名单标准。在编码时使用与解码时相同的标准将使您能够成功解码。
当我使用获取请求从我的核心数据实体获取时,我收到了用户的崩溃报告。这是崩溃的样子:
SIGABRT: Unhandled error (NSCocoaErrorDomain, 4864) occurred during faulting and was thrown: Error Domain=NSCocoaErrorDomain Code=4864 "The data couldn’t be read because it isn’t in the correct format." UserInfo={NSUnderlyingError=0x2822582d0 {Error Domain=NSCocoaErrorDomain Code=4864 "value for key 'NS.objects' was of unexpected class 'NSTextAlternatives (0x1ffa90890) [/System/Library/PrivateFrameworks/UIFoundation.framework]'. Allowed classes are '{( "NSTextAttachment (0x1ff3bc730) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSNumber (0x1ff35d8c8) [/System/Library/Frameworks/Foundation.framework]", "NSDictionary (0x1ff352418) [/System/Library/Frameworks/CoreFoundation.framework]", "NSFont (0x1ff3bc3e8) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSGlyphInfo (0x1ffa906d8) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSArray (0x1ff352238) [/System/Library/Frameworks/CoreFoundation.framework]", "NSParagraphStyle (0x1ff3bbec0) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSUUID (0x1ff35f290) [/System/Library/Frameworks/Foundation.framework]", "NSDate (0x1ff3522b0) [/System/Library/Frameworks/CoreFoundation.framework]", "NSColor (0x1ff3a67a8) [/System/Library/PrivateFrameworks/UIKitCore.framework]", "NSNull (0x1ff3527b0) [/System/Library/Frameworks/CoreFoundation.framework]", "NSData (0x1ff3519c8) [/System/Library/Frameworks/CoreFoundation.framework]", "UIColor (0x1ff3a6a78) [/System/Library/PrivateFrameworks/UIKitCore.framework]", "NSAttributedString (0x1ff359c00) [/System/Library/Frameworks/Foundation.framework]", "NSURL (0x1ff352e18) [/System/Library/Frameworks/CoreFoundation.framework]", "NSSet (0x1ff352878) [/System/Library/Frameworks/CoreFoundation.framework]", "NSValue (0x1ff35d940) [/System/Library/Frameworks/Foundation.framework]", "UIFont (0x1ff3bc780) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSString (0x1ff35d170) [/System/Library/Frameworks/Foundation.framework]" )}'." UserInfo={NSDebugDescription=value for key 'NS.objects' was of unexpected class 'NSTextAlternatives (0x1ffa90890) [/System/Library/PrivateFrameworks/UIFoundation.framework]'. Allowed classes are '{( "NSTextAttachment (0x1ff3bc730) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSNumber (0x1ff35d8c8) [/System/Library/Frameworks/Foundation.framework]", "NSDictionary (0x1ff352418) [/System/Library/Frameworks/CoreFoundation.framework]", "NSFont (0x1ff3bc3e8) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSGlyphInfo (0x1ffa906d8) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSArray (0x1ff352238) [/System/Library/Frameworks/CoreFoundation.framework]", "NSParagraphStyle (0x1ff3bbec0) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSUUID (0x1ff35f290) [/System/Library/Frameworks/Foundation.framework]", "NSDate (0x1ff3522b0) [/System/Library/Frameworks/CoreFoundation.framework]", "NSColor (0x1ff3a67a8) [/System/Library/PrivateFrameworks/UIKitCore.framework]", "NSNull (0x1ff3527b0) [/System/Library/Frameworks/CoreFoundation.framework]", "NSData (0x1ff3519c8) [/System/Library/Frameworks/CoreFoundation.framework]", "UIColor (0x1ff3a6a78) [/System/Library/PrivateFrameworks/UIKitCore.framework]", "NSAttributedString (0x1ff359c00) [/System/Library/Frameworks/Foundation.framework]", "NSURL (0x1ff352e18) [/System/Library/Frameworks/CoreFoundation.framework]", "NSSet (0x1ff352878) [/System/Library/Frameworks/CoreFoundation.framework]", "NSValue (0x1ff35d940) [/System/Library/Frameworks/Foundation.framework]", "UIFont (0x1ff3bc780) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "NSString (0x1ff35d170) [/System/Library/Frameworks/Foundation.framework]" )}'.}}}CrashVersion 5.6.8 (5.6.9)1 user1 report
当 NSFetchedResultsController
调用 performFetch
:
7 CoreData 0x00000001b48c1a94 __43-[NSFetchedResultsController performFetch:]_block_invoke + 572 8 CoreData 0x00000001b487c01c developerSubmittedBlockToNSManagedObjectContextPerform + 152 9
CoreData 0x00000001b474eda4 -[NSManagedObjectContext performBlockAndWait:] + 204 10 CoreData 0x00000001b475cae4 -[NSFetchedResultsController _recursivePerformBlockAndWait:withContext:] + 144 11 CoreData 0x00000001b475cc1c -[NSFetchedResultsController performFetch:] + 220
这几乎肯定会发生,因为我最近将一个没有任何转换器集的可转换属性(因此基本上使用 NSKeyedUnarchiveFromDataTransformerName
)更改为使用 NSSecureUnarchiveFromDataTransformer
的子 class .该属性正在存储来自 iOS 应用程序中的 UITextView
的 NSAttributedString
。我还将 'bold' 和 'italics' 项目的 NSRange 保存为 NSValue。
我添加了以下转换器:
@objc(AttributedStringDictionaryTransformer)
final class AttributedStringDictionaryTransformer: NSSecureUnarchiveFromDataTransformer {
override static var allowedTopLevelClasses: [AnyClass] {
return super.allowedTopLevelClasses + [NSValue.self]
}
}
这个'transformer'用于核心数据模型中的Transformable属性。它将 NSValue
class 添加到 classes.
当它说“键 'NS.objects' 的值是意外的 class 'NSTextAlternatives”时......我不确定 NSTextAlternatives
是什么。我从来没有(明确地)在我的代码中使用过它。任何想法可能来自哪里?
编辑:
在进一步调查中,事实证明 NSAttributedString 可以附加各种对象,例如 NSTextAlternatives
和 _UITextInputDictationResultMetadata
的对象,如果用户在 UITextView 上使用听写,这些对象可能会出现。所以技术上支持 NSAttributedString 的 NSSecureUnarchiveFromDataTransformer
实际上并没有正确支持它。这些 classes 来自私有框架,所以不确定如何将它们添加到我的自定义转换器中。除了提交错误外,不确定是否有其他解决方法。如果有,请告诉我。
事实上,NSAttributedString
可能有点像文本系统相关属性的抓包:文本视图中的各种操作可能导致文本系统(CoreText、UIKit 等)注释范围使用一些元数据来改善 iOS 体验,但这确实意味着任何给定的 NSAttributedString
最终都会带来一些您可能没有意识到的包袱。 (从概念上讲,NSAttributedString
就像一个 NSString
和一个关联的 NSDictionary
,它可以包含 任何东西 ,如果你斜眼看的话。)文本的常规使用视图可能会导致这种情况,当您也考虑从 other 属性字符串源粘贴文本时,您最终可能会得到许多您不期望的属性值。这是按预期工作的文本系统。
不幸的是,这种设计与 NSSecureCoding
相冲突,后者要求您在解码之前列出您希望从存档中解码的类型。你正确地将 NSAttributedString
和 NSValue
对象列入白名单,并且 NSAttributedString
本身将它知道的几种类型列入白名单(并且 NSSecureUnarchiveFromDataTransformer
也允许一些已知的 Foundation 类型),但是问题是字符串最终包含 neither 你 nor NSAttributedString
知道的类型,并且如果不将这些列入白名单,解码将被阻止。
由于这些类型确实是私有的,您将很难找到文本系统可能抛给您的所有可能的私有类型。最简单的方法是在 encoding 方面:在对 NSAttributedString
进行编码之前,遍历其所有属性范围并删除类型不符合您的任何属性白名单标准。在编码时使用与解码时相同的标准将使您能够成功解码。