2015-06-09 16 views
20

Tôi vừa mới tải xuống bản beta Xcode 7.0 mới và đã di chuyển từ Swift 1.2 sang Swift 2. Quá trình di chuyển dường như không thay đổi toàn bộ mã, thực tế là phương thức saveContext() tốt cho đến khi ném 2 lỗi cho các dòng:Swift 2 migration saveContext() trong appDelegate

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

hành Binary '& &' không thể được áp dụng cho hai toán hạng Bool

Gọi có thể ném, nhưng nó không được đánh dấu với 'thử' và lỗi không được xử lý

Phương pháp này trông như thế này:

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

Bất kỳ ý tưởng về làm thế nào để có được nó đang làm việc?

Trả lời

33

Lỗi đầu tiên trong số hai lỗi bạn cung cấp là gây hiểu lầm, nhưng lỗi thứ hai là vị trí bật. Vấn đề là trong !moc.save() mà kể từ Swift 2, không còn trả về Bool và thay vào đó được chú thích throws. Điều này có nghĩa là bạn phải try phương thức này và catch bất kỳ ngoại lệ nào mà nó có thể phát ra, thay vì chỉ kiểm tra lại giá trị trả về của nó là đúng hoặc sai.

Để phản ánh điều này, một dự án mới được tạo trong Xcode 7 bằng cách sử dụng Dữ liệu cốt lõi sẽ tạo ra mã bản mẫu sau đây có thể thay thế mã bạn đang sử dụng.

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

Cảm ơn bạn đó là câu trả lời đúng, Ngoài ra, Bạn cần phải thêm một '' sau khi managedObjectContext do đó, dòng trông giống như:! 'Nếu managedObjectContext .hasChanges {' và 'thử managedObjectContext lệnh .save()' – kalafun

+0

@ kalafun Không, trong Xcode 7 managedObjectContext không phải là tùy chọn. Sẽ đăng cập nhật trên câu trả lời của tôi – Ian

+0

Điều đó là lạ Tôi đang sử dụng xcode 7 beta và nó đã ném một lỗi vì dấu chấm than bị thiếu. Đang chờ cập nhật của bạn .. – kalafun

9

Câu trả lời bởi 0x7fffffff là đúng, nhưng để cải tiến mã boilerplate của Apple, bạn có thể bắt các lỗi cụ thể trong khối catch sử dụng catch let error as NSError như vậy:

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

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

Cách tốt nhất là sử dụng var error phù thủy vẫn sẽ có mặt nếu bạn chỉ sử dụng nó theo cách này:

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

Trong cùng một cách, nếu bạn chắc chắn rằng managedObjectContext.save() sẽ không throw một exception, mã được rút gọn xuống:

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

Và để suy luận về lý do tại sao managedObjectContext là không bắt buộc trong các mã Swift 2, đó là vì các NSManagedObject(concurrencyType:) là một initializer mà không thất bại. Trong Xcode 6, mã boilerplate trả về một ngữ cảnh tùy chọn nếu NSPersistentStoreCoordinator là không, nhưng bạn có thể xử lý điều này một cách dễ dàng bằng cách kiểm tra.

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