CoreData: peringatan: Tidak dapat memuat kelas bernama

94

Saya menduplikasi aplikasi Acara TV Objective-C yang ada ke versi Swift baru menggunakan Xcode 6.1 dan saya mengalami beberapa masalah dengan CoreData.

Saya telah membuat model 4 entitas, membuat subkelas NSManagedObject mereka (di Swift), dan semua file memiliki target aplikasi yang tepat (untuk 'Sumber Kompilasi').

Saya masih mendapatkan kesalahan ini setiap kali saya mencoba memasukkan entitas baru:

CoreData: peringatan: Tidak dapat memuat kelas bernama 'Shows' untuk entitas 'Shows'. Kelas tidak ditemukan, menggunakan NSManagedObject default sebagai gantinya.

Beberapa komentar:

Saat menyimpan ke Data Inti, saya menggunakan cara konteks orang tua-anak untuk memungkinkan penguliran latar belakang. Saya melakukan ini dengan menyiapkan ManagedObjectContext menggunakan:

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

dan dengan menyimpan data menggunakan:

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...
})
JimmyJammed
sumber

Jawaban:

177

Peringatan ini adalah salah satu kebiasaan yang harus kami tangani sementara detail implementasi Swift sedang diselesaikan. Peringatan muncul secara tidak benar, yaitu pengaturan Anda mungkin berfungsi meskipun Anda tidak mengikuti langkah-langkah yang diuraikan di bawah ini.

Saya dapat menyingkirkannya dalam banyak kasus dengan memastikan bahwa kelas diatur dengan benar di editor model . Tidak seperti di banyak posting SOF lainnya (termasuk jawaban atas pertanyaan ini), saran untuk memasukkan nama modul (seperti MyApp.Shows) tidak membantu saya.

Pastikan Anda memeriksa ketiga item ini:

1.
Versi yang berfungsi hingga Xcode 7 beta 3

Hingga XCode7 b3

Perhatikan bahwa saya mengoreksi nama entitas Anda menjadi bentuk tunggal yang lebih sesuai.

Versi yang berfungsi untuk Swift 2.0 di Xcode 7.1
(Seharusnya berfungsi untuk Xcode 7 beta 4 dan lebih tinggi)

Anda perlu menghapus teks "Current Product Module" di Module!

Dari Xcode7 beta 3

2.
Anda juga harus mengikuti rekomendasi yang sering diberikan

@objc(Show)

tepat di atas kelas Anda.

Catatan : Jika Anda menggunakan Xcode 7 beta 4 atau lebih baru, langkah ini opsional.

3.
Juga pastikan untuk mentransmisikan objek terkelola yang telah dibuat ke kelas yang sesuai, karena defaultnya hanya NSManagedObject.

var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", 
                 inManagedObjectContext: context) as Show
Mundi
sumber
3
Terima kasih! Saya memang membuat pembaruan konvensi penamaan yang direkomendasikan, dan '@objc (Show)'-lah yang tampaknya melakukan trik dalam memperbaiki kesalahan 'Tidak dapat memuat kelas ...'. Sangat dihargai!
JimmyJammed
Hai @undi. Terima kasih banyak! apakah kamu masih ingat dimana sumbernya?
iamdavidlam
1
Lihat misalnya pertanyaan ini . Ada cukup informasi di sana untuk memahami apa yang sedang terjadi.
Mundi
4
Yang cukup menarik, saya harus menghapus @objc(MyClass)
Santa Claus
1
@Mundi, Anda mungkin ingin memperbarui jawaban Anda lagi. Lihat pembaruan jawaban khunshan.
Suragch
75

Pembaruan SWIFT 2 / XCODE 7:

Masalah ini (lihat komentar 3 April saya tentang jawaban ini juga) diselesaikan dalam rilis beta Swift 2 dan XCode 7 oleh Apple. Jadi Anda sebenarnya sekarang tidak perlu @objc(myEntity)menggunakan Swift seperti yang dijawab oleh Mundi atau menggunakan " MyAppName." sebelum nama Kelas Anda. Ini akan berhenti bekerja. Jadi hapus ini, cukup masukkan Classnama di File dan pilih Current Working Modulesebagai Modul dan tepuk tangan!

Memilih modul kerja saat ini

Tetapi bagi mereka yang menggunakan @objc(myEntity)Swift (seperti saya), Anda dapat menggunakan solusi lain ini yang berfungsi dengan lancar.

Di kelas xcdatamodel yang benar masuk Ini akan terlihat seperti ini:

Mengatur kelas

Ini dia. Module.Classadalah pola untuk CoreData di Swift dan XCode 6. Anda juga memerlukan prosedur yang sama saat menggunakan kelas Kebijakan Kustom dalam Kebijakan Model atau hal-hal CoreData lainnya. Catatan: Dalam gambar, Nama dan Kelas harus Mobil dan MyAppName.Car (atau apa pun nama entitas Anda). Di sini, Userada kesalahan ketik.

khunshan
sumber
Masalah dengan solusi ini adalah kelas entitas yang dibuat secara otomatis tidak lagi berfungsi dengan baik (hanya akan menghasilkan satu kelas dengan nama modul). Lihat: Membuat subkelas NSManagedObject tidak menghasilkan dengan benar .
milos
Anda perlu menerapkan solusi setelah membuat kelas entitas NSManagedObject. Mungkin bug xcode 6.xx harus dihapus.
khunshan
2
Ya, ini pasti akan diselesaikan. Kelas yang dibuat secara otomatis harus sudah dihiasi dengan @objc (<nama kelas seperti yang dimasukkan di inspektur entitas>) atau, lebih mungkin, Apple akan membuat ini tidak perlu untuk memulai.
milos
2
Untuk orang yang masih membaca ini. menggunakan ' MyAppName.Car ' tidak berhasil untuk saya, itu berhasil ketika saya menghapus ' MyAppName. 'bagian. Jadi hanya Caruntuk kedua bidang itu berhasil.
Gideon
1
kamu Champ !!!! biarkan person = NSEntityDescription.insertNewObject (forEntityName: "Person", into: context) as! Orang
Abimanyu Rathore
36

Saat menggunakan Xcode 7 dan Swift murni, saya benar-benar harus menghapus @objc(MyClass) dari NSManagedObjectsubclass yang dibuat secara otomatis (dihasilkan dari Editor> Create NSManagedObject Subclass...).

Sinterklas
sumber
4
Wow terima kasih telah memposting jawaban ini. Aku akan mulai membenturkan kepalaku ke dinding.
Zia
Masalah yang sama di sini - Mengirimkan bug.
MirekE
Bekerja untuk saya juga. Harus menghapusnya. Aneh.
Kent
Menurut eksperimen saya, ini terlihat seperti positif palsu.
Mundi
Saya harus menghapusnya dan mengatur Modul Produk Saat Ini, baru setelah itu berhasil
Oleg Sherman
13

Dalam Xcode 7 beta 2 (dan saya percaya 1), dalam konfigurasi model, jenis objek yang dikelola baru Filediatur ke Modul Current Product Moduledan kelas objek ditampilkan dalam konfigurasi sebagai .File.

Modul jenis objek terkelola disetel ke "Modul Produk Saat Ini" di Xcode 7

Menghapus pengaturan modul sehingga kosong, atau menghapus tanda titik sehingga nama kelas dalam konfigurasi hanyalah Filetindakan yang setara, karena masing-masing menyebabkan perubahan lainnya. Menyimpan konfigurasi ini akan menghapus kesalahan yang dijelaskan.

Modul objek terkelola disetel kosong di Xcode 7

Duncan Babbage
sumber
9

Di Xcode 6.1.1 Anda tidak perlu menambahkan atribut @objc karena entitas dasar adalah bagian dari kelas objc (NSManagedObject) (lihat Kompatibilitas Tipe Swift . Di CoreData, nama Module.Class lengkap diperlukan. name adalah apa yang disetel di Setelan Bangun -> Pengemasan -> Nama Modul Produk. Secara default disetel ke $ (PRODUCT_NAME: c99extidentifier) ​​yang akan menjadi nama Target .

Jim Malak
sumber
Iya! Ini adalah jawaban modern (xcode 6.3.2). Menggunakan nama bundel yang tepat adalah kuncinya. Dalam kasus saya, itu telah berubah my-productmenjadi my_product, dan ini membuat semua perbedaan pada Data Inti.
SimplGy
5

Dengan versi xCode 7 dan Swift 2.0, Anda tidak perlu menambahkan @objc (NameOfClass), cukup ubah pengaturan entitas di tab "Tampilkan Inspektur Model Data" seperti di bawah -

Nama - "Nama Entitas Anda"

Kelas - "Nama Entitas Anda"

Modul - "Modul Produk Saat Ini"

masukkan deskripsi gambar di sini

Kode untuk file kelas Entitas akan seperti (dalam kode saya Entitas adalah Keluarga) -

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

Contoh ini berfungsi dengan baik di aplikasi saya dengan xCode 7.0 + swift 2.0

Himanshu Mahajan
sumber
3

Jangan lupa ganti PRODUCT_MODULE_NAMEdengan nama modul produk Anda.

Saat entitas baru dibuat, Anda harus masuk ke Pemeriksa Model Data (tab terakhir) dan mengganti PRODUCT_MODULE_NAMEdengan nama modul Anda, atau itu akan mengakibatkan class not foundkesalahan saat membuat koordinator penyimpanan persisten.

Kof
sumber
2

Anda juga perlu menggunakan (setidaknya dengan Xcode 6.3.2) Module.Class saat melakukan cast Anda misalnya: Dengan asumsi modul Anda (yaitu nama produk) adalah Makanan dan kelas Anda adalah Buah

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

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

Rekap:

  • Sertakan nama modul saat mendefinisikan entitas di Editor Model Data (Nama: Buah, Kelas: Makanan, Buah)
  • Saat mengakses entitas dalam kode (ieSWIFT), transmisikan dengan Module.class (misalnya Food.Fruit)
Wizkid
sumber
Terima kasih, poin kedua sangat penting. Saya harus menggunakan "Module.Class" saat mentransmisikannya.
Zoyt
1

Mengubah nama Kelas Entitas di editor Model Data agar sesuai dengan kelas yang dimaksud dan menambahkan @objc(NameOfClass)ke file dari setiap NSManagedObject tepat di atas deklarasi kelas memecahkan masalah ini untuk saya selama Pengujian Unit.

pengguna3269767
sumber
0

Apa yang berhasil untuk saya (Xcode 7.4, Swift) adalah mengubah nama kelas menjadi <my actual class name>.<entity name> di inspektur Entitas, kotak 'Kelas'.

Pemrakarsa saya dari subkelas objek Terkelola, terlihat seperti ini:

    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
menandai
sumber
0

Untuk Xcode 11.5: jika properti Codegen adalah class Definition, dan jika Anda tidak mendapatkan saran untuk entitas yang Anda buat di xcdatamodel. Coba keluar dari Xcode dan buka kembali proyek Anda. Ini bekerja untuk saya. Jawaban ini hanya jika Anda tidak mendapatkan saran tetapi jika file Anda tidak dihasilkan, coba jawaban di atas.

Gulshan Kumar
sumber