2015-06-09 6 views
20

Ich habe gerade die neue Xcode 7.0 Beta heruntergeladen und eine Migration von Swift 1.2 nach Swift 2 durchgeführt. Die Migration hat offenbar nicht den ganzen Code geändert, sondern eine Methode saveContext() gut, bis 2 Fehler für die Linie wirft:Swift 2 Migration saveContext() in AppDelegate

if moc.hasChanges && !moc.save() { 

Binäroperators '& &' auf zwei Bool-Operanden

und

nichtangewendet werden 210

Anruf kann werfen, aber es ist nicht mit ‚versuchen‘ markiert und der Fehler wird nicht

Das Verfahren sieht wie folgt behandelt:

// 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() 
     } 
    } 
} 

Irgendwelche Ideen auf, wie man es bekommt Arbeiten?

Antwort

33

Der erste der beiden Fehler, die Sie angegeben haben, ist irreführend, aber der zweite ist genau richtig. Das Problem ist in !moc.save(), die ab Swift 2 Bool nicht mehr zurückgibt und stattdessen throws annotiert wird. Dies bedeutet, dass Sie müssen try diese Methode und catch alle Ausnahmen, die es emittieren kann, anstatt nur zu überprüfen, ob der Rückgabewert wahr oder falsch ist.

Um dies widerzuspiegeln, wird ein neues Projekt, das in Xcode 7 mit Core Data erstellt wurde, den folgenden Standardcode erzeugen, der den von Ihnen verwendeten Code ersetzen kann.

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() 
     } 
    } 
} 
+1

Danke, das ist die richtige Antwort, Darüber hinaus benötigen Sie einen '' nach managedObjectContext hinzufügen, damit die Zeile wie folgt aussieht:!! 'Wenn managedObjectContext .hasChanges {' und 'versuchen managedObjectContext .save()' – kalafun

+0

@kalafun Nein, in Xcode 7 ist der managedObjectContext nicht optional. Wird Update auf meine Antwort posten – Ian

+0

Das ist seltsam, ich benutze xcode 7 beta und es warf einen Fehler wegen der fehlenden Ausrufezeichen. Warten auf Ihr Update .. – kalafun

9

Die Antwort von 0x7fffffff ist richtig, aber auf Apples Standardcode zu verbessern, können Sie den spezifischen Fehler im catch-Block mit catch let error as NSError fangen wie folgt:

func saveContext() { 
    if managedObjectContext.hasChanges { 
     do { 
      try managedObjectContext.save() 
     } catch let error as NSError { 

      NSLog("Unresolved error \(error), \(error.userInfo)") 
      // Handle Error 
     } 
    } 
} 

Die beste Vorgehensweise zu verwenden ist die var error Hexe immer noch verfügbar, wenn Sie es nur auf diese Weise verwenden:

func saveContext() { 
     if managedObjectContext.hasChanges { 
      do { 
       try managedObjectContext.save() 
      } catch { 
       NSLog("Unresolved error \(error), \(error.userInfo)") 
       // Handle Error 
      } 
     } 
    } 

In gleicher Weise, wenn Sie sicher sind, dass managedObjectContext.save() nicht throw ein exception, wird der Code abgespeckt:

func saveContext() { 
    if managedObjectContext.hasChanges { 
     try! managedObjectContext.save() 
    } 
} 

Und auf extrapolieren warum managedObjectContext nicht optional im Code Swift 2 ist, ist es, weil die NSManagedObject(concurrencyType:) ein initializer ist, die nicht ausfällt. In Xcode 6 hat der Boilerplate-Code einen optionalen Kontext zurückgegeben, wenn die NSPersistentStoreCoordinator Null ist, aber Sie können dies leicht durch Überprüfung übernehmen.

lazy var managedObjectContext: NSManagedObjectContext = { 
    let coordinator = self.persistentStoreCoordinator 
    var moc = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
    moc.persistentStoreCoordinator = coordinator 
    return moc 
}()