【发布时间】:2021-12-26 15:18:36
【问题描述】:
我的 CoreData 实体文件中有几个名为 UnsavedModel 的属性,这里是其中的一些。
我使用 CollectionView 创建了自己的文件,当我实例化 newBodyText 和 newHttpsStr 属性时,它崩溃了。正确的值被输入到这两个属性中,它们只是字符串,但它只会在这些属性上崩溃,而不会在其他属性上崩溃。 如果我不给这些属性赋值,一切都会正常。这里有什么问题?
问题出现顺序如下:
- HomeVC > buttonPress 立即按下 UnsavedVC
- UnsavedVC(正确加载单元格)> backButtonPressed 立即弹回 HomeVC
- HomeVC > buttonPress 立即按下 UnsavedVC
- 崩溃
仅供参考,我在写入这些属性时没有问题。但是当我尝试删除这 2 个属性时,它会崩溃,但删除任何其他属性都没有问题。
我在Thread 1 Queue : com.apple.main-thread (serial) 上也遇到了同样的问题。
代码:
class UnsavedController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var datasource = [CopyCoreDataModel]()
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func fetchData() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let context = appDelegate.persistentContainer.viewContext
// I also tried context.performAndWait { ... run the do-try-catch fetchRequest in here... }
let fetchRequest: NSFetchRequest<UnsavedModel> = UnsavedModel.fetchRequest()
do {
let results = try context.fetch(fetchRequest)
for result in results {
guard let id = result.value(forKey: "id") as? String else { continue }
let isContained = tableData.contains(where: { $0.id ?? "" == id })
if !isContained {
let copy = CopyCoreDataModel(id: id, unsavedModel: result)
datasource.append(copy)
}
}
collectionView.reloadData()
} catch {
print(error)
}
}
}
// CopyCoreDataModel is necessary because I run some functions based on certain properties
class CopyCoreDataModel {
var fileUrl: URL?
var id: String?
var unsavedModel: UnsavedModel?
var postDate: Double?
// otherProperties of type String, Double, and Boolean
var micUrl: String?
var newBodyText: String?
var newHttpsStr: String?
init(id: String, unsavedModel: UnsavedModel) {
self.id = id
self.unsavedModel = unsavedModel
// self otherProperties = unsavedModel.otherProperties // run some function on some of the other properties. These all work perfectly fine
if let micUrl = unsavedModel.micUrl { // works perfectly fine
self.micUrl = micUrl
// function to get micURL from FileManager that eventually sets self.fileUrl
}
if let newBodyText = unsavedModel.newBodyText { // crash occurs here only if it has a value
self.newBodyText = newBodyText
}
if let newHttpsStr = unsavedModel.newHttpsStr { // crash occurs here only if it has a value
self.newHttpsStr = newHttspStr
}
}
}
func writeData(micURL: URL) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
let entity: NSEntityDescription = NSEntityDescription.entity(forEntityName: "UnsavedModel", in: context)!
let object: NSManagedObject = NSManagedObject(entity: entity, insertInto: context)
object.setValue(UUID().uuidString, forKey: "id")
object.setValue(micURL.path, forKey: "micUrl")
object.setValue("abc", forKey: "newBodyText")
object.setValue("https...", forKey: "newHttpsStr")
// set other properties
do {
try context.save()
} catch let error as NSError {
print("could not save . \(error), \(error.userInfo)")
}
}
我还设置了一个类似 this 的 sharedInstance 并通过 let context = CoreDataManager.sharedManager.persistentContainer.viewContext 访问了上下文,但出现了同样的问题
更新
我还更改了 CopyCoreDataModel 的初始化程序以使用来自 unsavedModel 的 k/v 字典,但崩溃仍然发生
class CopyCoreDataModel {
// same exact properties
init(id: String, dict: [String: Any]) {
// set the properties using the values from the dict
}
}
func fetchData() {
let context = // ...
let fetchRequest = // ...
do {
let results = try context.fetch(fetchRequest)
for result in results {
guard let id = result.value(forKey: "id") as? String else { continue }
let isContained = datasource.contains(where: { $0.id ?? "" == id })
if !isContained {
let dict = createDictFromUnsavedModel(unsavedModel: result)
let copy = CopyCoreDataModel(id: id, dict: dict)
datasource.append(copy)
}
}
collectionView.reloadData()
} catch {
}
}
func createDictFromUnsavedModel(unsavedModel: UnsavedModel) -> [String:Any] {
var dict = [String: Any]()
// set dict using k/v from unsavedModel
return dict
}
【问题讨论】:
-
可能不相关,但不应该是
self.newHttspStr = newHttspStr而不是self.newBodyText = newHttspStr? -
哦,是的,这是一个错字,我的实际代码中没有(它是正确的)。让我修复它。谢谢!我想我刚刚发现了这个问题。我正在测试它并即将发布。我认为修复它的修复并没有修复它
-
@vadian 我认为您应该在下面查看此答案。我知道你在这方面非常熟练,但这是一件很容易被忽视的事情。也许你会再次遇到这种情况。谢谢你的帮助顺便说一句!!!