Я новичок в Swift, и у меня возникают проблемы с пониманием того, как работают переменные среды.
В Core Data я создал новую сущность под названием «API» с одним атрибутом id: Int32.
Затем в SwiftUI я хотел найти максимальное значение id. Я написал запрос, но всякий раз, когда я использовал аргумент, передаваемый для просмотра в качестве переменной среды managedObjectContext, он всегда приводил к краху моего приложения / предварительного просмотра. Вот краткая sh информация после использования NSManagedObjectContext.fetch (NSFetchRequest) (использование FetchRequest дает только трассировку стека с исключением EXC_BAD_INSTRUCTION)
...
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
External Modification Warnings:
Thread creation by external task.
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The fetch request's entity 0x600003c54160 'API' appears to be from a different NSManagedObjectModel than this context's'
terminating with uncaught exception of type NSException
abort() called
CoreSimulator 704.12 - Device: iPhone 11 (8356FF2A-5F0A-42F7-AA32-396FADCF2BF6) - Runtime: iOS 13.4 (17E255) - DeviceType: iPhone 11
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff23e3dcce __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50b3b9b2 objc_exception_throw + 48
2 CoreData 0x00007fff239c6b99 -[NSManagedObjectContext executeFetchRequest:error:] + 5004
3 libswiftCoreData.dylib 0x00007fff513b63d4 $sSo22NSManagedObjectContextC8CoreDataE5fetchySayxGSo14NSFetchRequestCyxGKSo0gH6ResultRzlF + 68
...
Имейте в виду, что эта ошибка меняется в зависимости от того, какой проект, я с помощью. В моем основном проекте у меня была такая ошибка:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'WebsiteAPI''
Вот код, который я использую
import SwiftUI
import CoreData
struct test: View {
private var id: Int32
@Environment(\.managedObjectContext) var managedObjectContext
var body: some View {
Text("id=\(id)")
}
public init(context: NSManagedObjectContext) {
self.id = -1
//this crashes and gives no usefull information
// let request2 = FetchRequest<API>(
// entity: API.entity(),
// sortDescriptors: [NSSortDescriptor(keyPath: \API.id, ascending: false)]
// )
// self.id = request2.wrappedValue.first?.id ?? 1
guard let context2 = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
fatalError("Unable to read managed object context.")
}
let request = NSFetchRequest<API>(entityName: "API")
request.sortDescriptors = [NSSortDescriptor(keyPath: \API.id, ascending: false)]
do {
var commits = try context.fetch(request) // OK
commits = try context2.fetch(request) // OK
//commits = try self.managedObjectContext.fetch(request) // causing crash
self.id = Int32(commits.count)
} catch let error {
print(error.localizedDescription)
}
}
}
struct test_Previews: PreviewProvider {
static var previews: some View {
guard let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
fatalError("Unable to read managed object context.")
}
return test(context: context).environment(\.managedObjectContext, context)
}
}
Все прокомментированные строки cra sh app. Почему получение контекста из AppDelegate.persistentContainer.viewContext работает просто отлично, но использование переменной среды managedObjectContext, которая, по моему мнению, должна быть такой же, не работает? Я потратил на это 5 часов, почти все проверил, много чего перепробовал, но безуспешно. В конце концов, я могу продолжать получать контекст из AppDelegate, но что не так с переменной среды? Я скучаю по некоторым общим знаниям или это просто ошибка? Я получаю головную боль от ошибок, с которыми я сталкиваюсь в XCode, начиная с отсутствия автодополнения после очистки папки сборки до сотен ошибок после изменения имени структуры / файла во всех ссылках, несмотря на успешную сборку впоследствии. Для меня нормально перезапускать Xcode несколько раз в день, чтобы он работал нормально.
Также некоторые вещи, которые я заметил, когда я создал FetchRequest как переменную и использовал его в каком-то списке внутри тела, это работало. Проблема только в том, что когда я пытаюсь получить что-то вручную в коде / функции / init, например, действие кнопки или методы onAppear, init et c. Я пытался запустить приложение на физическом устройстве и показывать предварительный просмотр. Тот же эффект.
Я использую Xcode 11.4 со Swift 5.