CoreData: cảnh báo: Không thể tải lớp có tên


94

Tôi đang sao chép ứng dụng Objective-C TV Show hiện có sang phiên bản Swift mới bằng Xcode 6.1 và đang gặp một số sự cố với CoreData.

Tôi đã tạo một mô hình gồm 4 thực thể, tạo lớp con NSManagedObject của chúng (trong Swift) và tất cả các tệp đều có mục tiêu ứng dụng thích hợp được đặt (cho 'Nguồn biên dịch').

Tôi vẫn gặp lỗi này bất cứ khi nào tôi cố gắng chèn một thực thể mới:

CoreData: cảnh báo: Không thể tải lớp có tên 'Shows' cho thực thể 'Shows'. Không tìm thấy lớp, sử dụng NSManagedObject mặc định để thay thế.

Một vài nhận xét:

Khi lưu vào Dữ liệu cốt lõi, tôi sử dụng cách ngữ cảnh mẹ-con để cho phép phân luồng nền. Tôi thực hiện việc này bằng cách thiết lập ManagedObjectContext bằng cách sử dụng:

lazy var managedObjectContext: NSManagedObjectContext? = {
  // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
  let coordinator = self.persistentStoreCoordinator
  if coordinator == nil {
    return nil
  }
  var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
  managedObjectContext.persistentStoreCoordinator = coordinator
  return managedObjectContext
}()

và bằng cách lưu dữ liệu bằng cách sử dụng:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
  var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
  context.parentContext = self.managedObjectContext!
  ...rest of core data saving code here...
})

Câu trả lời:


177

Cảnh báo này là một trong những vấn đề mà chúng tôi phải đối phó trong khi chi tiết về việc triển khai Swift đang được hoàn thiện. Cảnh báo xảy ra ngẫu nhiên, tức là thiết lập của bạn có thể hoạt động ngay cả khi bạn không làm theo các bước được nêu bên dưới.

Tôi đã có thể loại bỏ nó trong hầu hết các trường hợp bằng cách đảm bảo rằng lớp được đặt chính xác trong trình chỉnh sửa mô hình . Không giống như trong nhiều bài đăng SOF khác (bao gồm cả câu trả lời cho câu hỏi này), đề xuất bao gồm tên mô-đun (như MyApp.Shows) đã không giúp được tôi.

Đảm bảo rằng bạn kiểm tra ba mục sau:

1.
Phiên bản hoạt động lên đến Xcode 7 beta 3

Lên đến XCode7 b3

Lưu ý rằng tôi đã sửa tên thực thể của bạn thành số ít thích hợp hơn.

Phiên bản hoạt động cho Swift 2.0 trong Xcode 7.1
(Nên hoạt động cho Xcode 7 beta 4 trở lên)

Bạn cần xóa dòng chữ "Mô-đun sản phẩm hiện tại" trong Mô-đun!

Từ Xcode7 beta 3

2.
Bạn cũng nên làm theo khuyến nghị thường xuyên để bao gồm

@objc(Show)

ngay trên lớp của bạn.

Lưu ý : Nếu bạn đang sử dụng Xcode 7 beta 4 trở lên, bước này là tùy chọn.

3.
Đồng thời đảm bảo truyền đối tượng được quản lý đã tạo sang lớp thích hợp, vì mặc định sẽ là đúng NSManagedObject.

var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", 
                 inManagedObjectContext: context) as Show

3
Cảm ơn! Tôi đã thực hiện cập nhật quy ước đặt tên được đề xuất và chính '@objc (Hiển thị)' dường như thực hiện thủ thuật trong việc sửa lỗi 'Không thể tải lớp ...'. Nhiều đánh giá cao!
JimmyJammed

Xin chào @Mundi. Cảm ơn bạn rất nhiều! bạn có còn nhớ nguồn ở đâu không?
iamdavidlam

1
Xem ví dụ câu hỏi này . Có đủ thông tin ở đó để hiểu những gì đang xảy ra.
Mundi

4
Điều thú vị là đủ, tôi phải loại bỏ @objc(MyClass)
ông già Noel

1
@Mundi, bạn có thể muốn cập nhật lại câu trả lời của mình. Xem cập nhật câu trả lời của khunshan.
Suragch

75

Cập nhật SWIFT 2 / XCODE 7:

Vấn đề này (xem cả nhận xét ngày 3 tháng 4 của tôi về câu trả lời này) đã được giải quyết trong Swift 2 Apple bản phát hành beta và XCode 7 . Vì vậy, bây giờ bạn thực sự không cần @objc(myEntity)sử dụng Swift như Mundi đã trả lời hoặc sử dụng " MyAppName." trước tên Lớp của bạn. Nó sẽ ngừng hoạt động. Vì vậy, hãy loại bỏ những thứ này, chỉ cần đặt Classtên trong Tệp và chọn Current Working Modulelàm Mô-đun và chúc mừng!

Chọn mô-đun làm việc hiện tại

Nhưng đối với những người sử dụng @objc(myEntity)Swift (như tôi), bạn có thể sử dụng giải pháp khác này để thay thế.

Trong lớp đúng xcdatamodel trong. Nó sẽ giống như sau:

Thiết lập lớp học

Của bạn đây. Module.Classlà mẫu cho CoreData trong Swift và XCode 6. Bạn cũng sẽ cần quy trình tương tự khi sử dụng lớp Chính sách tùy chỉnh trong Chính sách mô hình hoặc nội dung CoreData khác. Lưu ý: Trong hình ảnh, Tên và Hạng phải là Xe và MyAppName.Car (hoặc bất kỳ tên nào của thực thể của bạn). Đây, Userlà một lỗi đánh máy.


Vấn đề với giải pháp này là các lớp thực thể tự động tạo sẽ không còn hoạt động bình thường (nó sẽ chỉ tạo ra một lớp có tên mô-đun). Xem: Tạo lớp con NSManagedObject không được tạo đúng cách .
milos

Bạn cần áp dụng giải pháp sau khi tạo các lớp thực thể NSManagedObject. Có thể là lỗi xcode 6.xx cần được gỡ bỏ.
khunshan

2
Có, điều này chắc chắn sẽ được giải quyết. Các lớp được tạo tự động phải được tô điểm bằng @objc (<tên lớp như được nhập trong trình kiểm tra thực thể>) hoặc, nhiều khả năng, Apple sẽ biến điều này trở nên không cần thiết khi bắt đầu.
milos

2
Đối với những người vẫn đọc này. sử dụng ' MyAppName.Car ' không hoạt động đối với tôi, nó hoạt động khi tôi xóa ' MyAppName. ' phần. Vì vậy, chỉ Carcho cả hai lĩnh vực đã làm thủ thuật.
Gideon

1
bạn Champ !!!! let person = NSEntityDescription.insertNewObject (forEntityName: "Person", into: context) as! Person
Abhimanyu Rathore

36

Khi sử dụng Xcode 7 và hoàn toàn là Swift, tôi thực sự phải xóa @objc(MyClass) khỏi NSManagedObjectlớp con được tạo tự động của mình (được tạo từ Editor> Create NSManagedObject Subclass...).


4
Wow cảm ơn vì đã đăng câu trả lời này. Tôi định đập đầu vào tường.
Zia

Vấn đề tương tự ở đây - Đã gửi lỗi.
MirekE

Làm việc cho tôi quá. Đã phải loại bỏ nó. Kỳ quái.
Kent

Theo các thí nghiệm của tôi, nó trông giống như một dương tính giả.
Mundi

Tôi đã phải gỡ bỏ nó và thiết lập mô-đun sản phẩm hiện tại, chỉ sau đó nó làm việc
Oleg Sherman

13

Trong Xcode 7 beta 2 (và tôi tin là 1), trong cấu hình mô hình, một đối tượng được quản lý mới của loại Fileđược đặt thành Mô-đun Current Product Modulevà lớp của đối tượng được hiển thị trong cấu hình dưới dạng .File.

Mô-đun của loại đối tượng được quản lý được đặt thành "Mô-đun sản phẩm hiện tại" trong Xcode 7

Xóa cài đặt mô-đun để nó trống hoặc xóa toàn bộ điểm dừng để tên lớp trong cấu hình chỉ Filelà các hành động tương đương, vì mỗi hành động gây ra thay đổi khác. Lưu cấu hình này sẽ loại bỏ lỗi được mô tả.

Mô-đun của đối tượng được quản lý được đặt để trống trong Xcode 7


9

Trong Xcode 6.1.1, bạn không cần phải thêm thuộc tính @objc vì thực thể cơ sở là một tập hợp con của lớp objc (NSManagedObject) (xem Tương thích kiểu Swift . Trong CoreData, cần có tên Module. Lớp đầy đủ. Lưu ý rằng Mô-đun tên là những gì được đặt trong Cài đặt bản dựng -> Bao bì -> Tên mô-đun sản phẩm. Theo mặc định, tên này được đặt thành $ (PRODUCT_NAME: c99extidentifier) ​​sẽ là tên của Target .


Đúng! Đây là câu trả lời hiện đại (xcode 6.3.2). Sử dụng đúng tên gói là chìa khóa. Trong trường hợp của tôi, nó đã chuyển đổi my-productthành my_product, và điều này tạo nên sự khác biệt cho Dữ liệu cốt lõi.
SimplGy

5

Với phiên bản xCode 7 và Swift 2.0, bạn không cần thêm @objc (NameOfClass), chỉ cần thay đổi cài đặt thực thể trong tab "Show the Data Model Inspector" như bên dưới:

Tên - "Tên pháp nhân của bạn"

Lớp - "Tên thực thể của bạn"

Mô-đun - "Mô-đun Sản phẩm Hiện tại"

nhập mô tả hình ảnh ở đây

Mã cho tệp lớp Thực thể sẽ như thế nào (trong mã của tôi Thực thể là Gia đình) -

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

Ví dụ này đang hoạt động tốt trong ứng dụng của tôi với xCode 7.0 + swift 2.0


3

Đừng quên thay thế PRODUCT_MODULE_NAME bằng tên mô-đun sản phẩm của bạn.

Khi một thực thể mới được tạo, bạn cần đi tới Trình kiểm tra mô hình dữ liệu (tab cuối cùng) và thay thế PRODUCT_MODULE_NAMEbằng tên mô-đun của bạn, nếu không sẽ dẫn đến class not foundlỗi khi tạo điều phối viên lưu trữ liên tục.


2

Bạn cũng cần sử dụng (ít nhất là với Xcode 6.3.2) Module.Class khi thực hiện cast của bạn, ví dụ: Giả sử module của bạn (tức là tên sản phẩm) là Food và class của bạn là Fruit

let myEntity =  NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext)

let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit

Tóm tắt:

  • Bao gồm tên mô-đun khi xác định thực thể trong Trình chỉnh sửa mô hình dữ liệu (Tên: Trái cây, Lớp: Thực phẩm. Tuyển dụng)
  • Khi truy cập thực thể trong mã (tức làSWIFT), truyền nó bằng Module.class (ví dụ: Food.Fruit)

Cảm ơn bạn, điểm thứ hai là rất quan trọng. Tôi đã phải sử dụng "Module.Class" khi truyền nó.
Zoyt


1

Thay đổi tên Lớp thực thể trong trình chỉnh sửa Mô hình dữ liệu để tương ứng với lớp được đề cập và thêm @objc(NameOfClass)vào tệp của từng NSManagedObject ngay trên khai báo lớp đã giải quyết được vấn đề này cho tôi trong quá trình Kiểm tra đơn vị.


0

Điều làm việc cho tôi (Xcode 7.4, Swift) đang thay đổi tên lớp thành <my actual class name>.<entity name> trong hộp kiểm tra Thực thể, 'Lớp'.

Trình khởi tạo lớp con của đối tượng Managed của tôi trông giống như sau:

    convenience init(<properties to init>) {
    let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
    self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
    //init properties here

0

Đối với Xcode 11.5: nếu thuộc tính Codegen là Định nghĩa lớp và nếu bạn không nhận được đề xuất cho thực thể bạn đã tạo trong xcdatamodel. Cố gắng thoát Xcode và mở lại dự án của bạn một lần nữa. Nó làm việc cho tôi. Câu trả lời này chỉ là nếu bạn không nhận được đề xuất nhưng nếu tệp của bạn không được tạo, hãy thử bất kỳ câu trả lời nào ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.