新しいXcode 7.0ベータ版をダウンロードし、Swift 1.2からSwift 2.に移行しました。移行によってコード全体が変更されたようには見えません行に2つのエラーをスローするまで問題なかったsaveContext()メソッド:
if moc.hasChanges && !moc.save() {
二項演算子 '&&'は2つのブールオペランドに適用できません
そして
呼び出しはスローできますが、 'try'とマークされておらず、エラーは処理されません
メソッドは次のようになります。
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save() {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
それを機能させる方法に関するアイデアはありますか?
指定した2つのエラーのうち最初のエラーは誤解を招く可能性がありますが、2番目のエラーは問題の原因です。問題は!moc.save()
にあります。これはSwift 2以降、Boolを返さなくなり、代わりにthrows
と注釈が付けられます。つまり、try
このメソッドとcatch
は、戻り値がtrueまたはfalseであるかどうかを確認するだけでなく、発生する可能性のある例外をすべて処理します。
これを反映するために、Core Dataを使用してXcode 7で作成された新しいプロジェクトは、使用しているコードを置き換えることができる次のボイラープレートコードを生成します。
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
0x7fffffffによる答えは正しいですが、Appleのボイラープレートコードを改善するには、次のように_catch let error as NSError
_を使用して、catchブロックで特定のエラーをキャッチできます。
_func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch let error as NSError {
NSLog("Unresolved error \(error), \(error.userInfo)")
// Handle Error
}
}
}
_
ベストプラクティスは、変数error
を使用することです。この方法で使用する場合は、引き続き使用できます。
_func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
NSLog("Unresolved error \(error), \(error.userInfo)")
// Handle Error
}
}
}
_
同様に、managedObjectContext.save()
がthrow
およびexception
にならないことが確実な場合、コードは次のようにスリム化されます。
_func saveContext () {
if managedObjectContext.hasChanges {
try! managedObjectContext.save()
}
}
_
また、Swift 2コードでmanagedObjectContext
がオプションではない理由を推定すると、NSManagedObject(concurrencyType:)
が失敗しない初期化子であるためです。 Xcode 6では、NSPersistentStoreCoordinator
がnilの場合、ボイラープレートコードはオプションのコンテキストを返しましたが、これをチェックすることで簡単に処理できます。
_lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var moc = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
moc.persistentStoreCoordinator = coordinator
return moc
}()
_