App在每台符合9.3+ 部署目标的设备上运行正常,但 iPad2除外。网址很好。适用于所有iPhone和其他所有iPad。崩溃发生在物理iPad2和模拟器iPad2 iOS 9.3上。
doc.save(to: target, for: .forCreating, completionHandler: {(success) in
if (success) {
print("Save succeeded")
}
} else {
print("Save failed")
}
})
这是崩溃的地方。到达此行的断点,并且不要在完成处理程序或打印中找到断点。再一次,只是iPad的一个型号。
崩溃日志已经过去了。对你们任何人都有意义吗?谢谢。
编辑:展开崩溃日志
答案 0 :(得分:1)
tl; dr:这是Swift Data类型中的一个错误。解决方案:在您的UIDocument contents(forType:)
实施中,更改此内容:
return data
到此:
return NSData(data:data)
更多信息:请注意,仅将data
投射到NSData无济于事:
return data as NSData
这不会让我们更进一步,因为这是问题的桥梁。我们已经桥接到NSData并且没有帮助。您必须创建一个不是Swift Data对象的全新对象。
更多信息:对于后来出现并希望对其进行测试的后代,可以如下可靠地再现崩溃。像往常一样创建一个新的Single View项目,带有一个app delegate和一个ViewController。在 ViewController.swift 文件中,输入:
import UIKit
class WhatsUpDoc: UIDocument {
var array = [String]()
override func load(fromContents contents: Any, ofType typeName: String?) throws {}
override func contents(forType typeName: String) throws -> Any {
let data = NSKeyedArchiver.archivedData(withRootObject: array)
return data // comment out this line to avoid the crash
return NSData(data:data)
}
}
class ViewController: UIViewController {
var doc : WhatsUpDoc?
override func viewDidLoad() {
super.viewDidLoad()
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let baseURL = documentsDirectory.appendingPathComponent("Untitled")
let doc = WhatsUpDoc(fileURL: baseURL)
self.doc = doc
self.doc!.save(to:self.doc!.fileURL, for: .forCreating)
}
}
将项目配置为部署目标为9.0,并确保您手头有9.0模拟器SDK。在窗口中>设备,给自己一个iPad 2模拟器。将该模拟器设置为项目的目标。运行,崩溃。评论说出来评论它的行,不要崩溃。
后期分析Q& A:
等等,那究竟是什么_的错误?你不是说你不能把Swift Data对象写到磁盘上,是吗?
不,它与UIDocument文件保存期间写入的特殊线程性质有关。请注意,我们在后台线程(OP的屏幕截图中的线程10或11)中崩溃。我们在中崩溃的方法是SwiftNSData
的方法,NSData由Swift数据包装。我们试图在这个后台线程上枚举数据的字节,但我们不能;据推测,这在某些设备类型(即32位设备)上不是线程安全的。我的解决方案是将Swift Data完全从图片中删除。
好的,事实证明这个错误已知;答案在这里给出:https://stackoverflow.com/a/41163395/341994那怎么样?
好的,但我在回答当前问题时独立地想出来了。直到后来我才发现其他问题和答案时才发现我正在进行搜索。所以我把当前的问题标记为重复,但是我的答案是出于历史目的,特别是。因为它给出了一个明确的测试用例(另一个问题没有)。
顺便说一句,我不知道为什么使用NSMutableData(data:)
比使用NSData(data:)
的解决方案更好,但这就是Apple所说的,所以让我们把它当作福音。