2014-10-17 19 views
27
class Alternative: NSManagedObject { 

    @NSManaged var text: String 
    @NSManaged var isCorrect: Bool 
    @NSManaged var image: NSData 
} 

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) { 
     let alternative = Alternative(entity: entity, insertIntoManagedObjectContext: context) as Alternative 
     alternative.text = text 
     alternative.isCorrect = isCorrect 
     return alternative 
} 

Tôi muốn thực hiện một phương pháp cho phép tôi khởi tạo đối tượng mới với cuộc gọi này:Cách tạo trình khởi tạo được chỉ định cho lớp con NSManagedObject trong Swift?

let newAlternative = Alternative("third platform", True, entityDescription, managedObjectContext) 

Nhưng tôi nhận được lỗi:

Convenience initializer for Alternative must delegate with self.init 

gì tôi cần phải thay đổi trong initalizer của tôi để làm công việc sử dụng ví dụ của tôi?

Trả lời

29

Một initializer tiện phải gọi initializer được chỉ định trên self:

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) { 
    self.init(entity: entity, insertIntoManagedObjectContext: context) 
    self.text = text 
    self.isCorrect = isCorrect 
} 

được gọi là

let newAlternative = Alternative(text: "third platform", isCorrect: true, 
    entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext) 

Bên cạnh đó, bạn cũng có thể di chuyển tạo ra các mô tả thực thể vào initializer tiện thay vì đi qua nó như một tham số (như thúc đẩy bởi câu trả lời Mundi của):

convenience init(text: String, isCorrect: Bool, insertIntoManagedObjectContext context: NSManagedObjectContext!) { 
    let entity = NSEntityDescription.entityForName("Alternative", inManagedObjectContext: context)! 
    self.init(entity: entity, insertIntoManagedObjectContext: context) 
    self.text = text 
    self.isCorrect = isCorrect 
} 
+0

Câu hỏi bổ sung nhanh @ martin-r: Tôi đang cố gắng đặt chúng vào một tiện ích mở rộng lên NSManagedObject. Bạn có nghĩ rằng điều này nên có thể, như tôi nhận được một lỗi biên dịch. Dường như đang tìm NS_DESIGNATED_INITIALIZER từ NSManagedObject.h để sử dụng. Có suy nghĩ gì không? – Damien

+0

@Damien: Không cần xem mã thực tế và thông báo lỗi chính xác. –

+0

https: //gist.github.com/dglancy/2f1e313cfcc7d61cff8c – Damien

9

Tôi chỉ đơn giản là đã làm điều này với một chức năng lớp:

class func newInstance(text: String, notes:String, 
        context: NSManagedObjectContext) -> Item { 
    var item = NSEntityDescription.insertNewObjectForEntityForName("Item", 
       inManagedObjectContext: context) as Item 
    item.notes = notes 
    item.text = text 
    return item 
} 

mà bạn có thể gọi như thế này (gần như là khá):

let item = Item.newInstance(text, notes:notes) 
+0

Vì vậy, không thể tạo trình khởi tạo được chỉ định bằng 'Thay thế (" nền tảng thứ ba ", True, entityDescription, managedObjectContext)'? Ý kiến ​​của tôi là nó không nhìn tốt với Alternative.newInstance (...) – hakonbogen

+2

+1 cho * không * cần phải vượt qua một mô tả thực thể vào initializer. –

+0

Bạn có thể đặt tên khác theo ý thích của bạn thay vì 'newInstance()'. Ngoài ra, bạn vẫn muốn các tham số được đặt tên, không chỉ là một danh sách tham số, nếu không mã của bạn sẽ ít có thể đọc được. - Tóm lại, giải pháp phương thức lớp không thực sự dài hơn hay kém thẩm mỹ hơn các trình khởi tạo khác. – Mundi

2

Bạn phải gọi một trình khởi tạo được chỉ định từ trình khởi tạo thuận tiện của bạn. Ngoài ra, bạn không trả lại bất cứ thứ gì từ bất kỳ bộ khởi tạo nào.

Để hoàn thành các quy tắc được mô tả trong tài liệu Swift của Apple, trước tiên bạn cần một trình khởi tạo được chỉ định cho lớp con của bạn, gọi init() của lớp cha, sau đó bạn có thể cung cấp trình khởi tạo thuận tiện. initializer được chỉ định từ khai báo lớp của nó.

này sẽ làm việc: (Cập nhật:. Taken vào tài khoản đó thuộc tính dữ liệu cốt lõi được đánh dấu bằng @NSManaged được khởi tạo tự động bởi thời gian chạy Cảm ơn @ Martin R)

init(text: String, isCorrect: Bool, image: NSData, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) { 
    super.init(entity: entity, insertIntoManagedObjectContext: context) 
} 

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) { 
    self.init(text: text, isCorrect: isCorrect, entity: entity, insertIntoManagedObjectContext: context) 
} 
+1

Các thuộc tính dữ liệu lõi (được đánh dấu bằng '@ NSManaged') được khởi động tự động bởi thời gian chạy. –

+0

Điều này sẽ gây ra sự cố. xem câu hỏi này: http://stackoverflow.com/questions/26202346/error-with-swift-and-core-data-fatal-error-use-of-unimplemented-initializer-i – rintaro

2

Swift giải pháp 3.1:

convenience init(text: String, isCorrect: Bool, image: NSData, moc: NSManagedObjectContext) { 
     let entity = NSEntityDescription.entity(forEntityName: "Alternative", in: moc) 
     self.init(entity: entity!, insertInto: moc) 
     // vars 
     self.text = text 
     self.isCorrect = isCorrect 
     self.image = image 
} 
Các vấn đề liên quan