Swift 5.5 で async/await 同時実行を使用して、次の taskGroup を作成しました。ここでは、onboardingMeter
Core Data から取得して、メーターを反復処理します。これは 5 回中 4 回程度は問題なく動作しますが、その後 iOS アプリがクラッシュします。iOS デバイスからアプリを削除してこれをテストし、最初からオンボーディングを実行します。これを 4 回、5 回、または 6 回連続して問題なく実行できる場合がありますが、次のエラーで突然クラッシュします。
2021-09-05 09:11:01.095537+0200 Curro[12328:1169419] [error] error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2021-09-05 09:11:01.095954+0200 Curro[12328:1169419] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
*** First throw call stack:
(0x1857b105c 0x19dc63f64 0x1858ba538 0x1858c5df8 0x1857c68bc 0x18ce313d8 0x18cd13314 0x18cd140cc 0x105616700 0x105626a90 0x185769ce4 0x185723ebc 0x1857373c8 0x1a0edd38c 0x1880dae9c 0x187e58864 0x18d36da2c 0x18d29ab70 0x18d27bf2c 0x1048bba04 0x1048bbab0 0x10551da24)
libc++abi: terminating with uncaught exception of type NSException
これは失敗したコードであり、let onboardingMeter = await OnboardingMeter.fromMeterDict
返されることはありません。失敗したときに2番目のprintステートメントが表示されません。
これは Swift ベータ版のエラーですか、それともここで間違いを犯したのでしょうか? 新しい iOS 15 ベータ版がリリースされ、iOS 15 の正式リリースが発表されたら、もう一度試してみます。
await withTaskGroup(of: OnboardingMeter.self) { group in
for (number, codableAddress) in meters {
group.addTask {
print("The following statement sometimes fails to return an onboarding meter, resulting in a crash")
let onboardingMeter = await OnboardingMeter.fromMeterDict(number, address: codableAddress, in: moc)
print("onboardingMeter:", onboardingMeter)
return onboardingMeter
}
}
for await meter in group {
onboardingMeters.append(meter)
}
}
OnboardingMeter.fromMeterDict
機能:
extension OnboardingMeter {
static func fromMeterDict(_ number: String, address: CodableAddress, in moc: NSManagedObjectContext) async -> OnboardingMeter {
let me: OnboardingMeter = await moc.findOrCreateInstance(of: self, predicate: NSPredicate(format: "number == \(number)"))
let address = await Address.createOrUpdate(from: address, in: moc)
await moc.perform {
me.address = address
me.number = number
}
return me
}
}
そしてfindOrCreateInstance:
func findOrCreateInstance<T: NSManagedObject>(of type: T.Type, predicate: NSPredicate?) async -> T {
if let found = await self.findFirstInstance(of: type, predicate: predicate) {
return found
} else {
return T(context: self)
}
}