CoreData: uyarı: adlı sınıf yüklenemiyor


95

Mevcut bir Objective-C TV Show uygulamasını Xcode 6.1 kullanarak yeni bir Swift sürümüne kopyalıyorum ve CoreData ile ilgili bazı sorunlar yaşıyorum.

4 varlıktan oluşan bir model oluşturdum, NSManagedObject alt sınıfını (Swift'de) oluşturdum ve tüm dosyaların uygun uygulama hedefleri ayarlanmış ('Derleme Kaynakları' için).

Yeni bir varlık eklemeye çalıştığımda hala bu hatayı alıyorum:

CoreData: uyarı: 'Gösteriler' varlığı için 'Gösteriler' adlı sınıf yüklenemiyor. Bunun yerine varsayılan NSManagedObject kullanılarak sınıf bulunamadı.

Birkaç yorum:

Çekirdek Verilere kaydederken, arka planda iş parçacığı oluşturmaya izin vermek için üst-alt bağlam yolunu kullanıyorum. Bunu, ManagedObjectContext'i kullanarak yapıyorum:

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

ve aşağıdakileri kullanarak verileri kaydederek:

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

Yanıtlar:


177

Bu uyarı, Swift uygulamasının detayları ortaya çıkarılırken uğraşmamız gereken tuhaflıklardan biri. Uyarı sahte bir şekilde gerçekleşir, yani aşağıda belirtilen adımları izlemeseniz bile kurulumunuz çalışabilir.

Çoğu durumda , model düzenleyicide sınıfın doğru ayarlandığından emin olarak ondan kurtulabildim . Diğer birçok SOF gönderisinden farklı olarak (bu sorunun yanıtları dahil), modül adını (beğeniyi MyApp.Shows) ekleme önerisi bana yardımcı olmadı .

Bu üç öğeyi kontrol ettiğinizden emin olun:

1.
Xcode 7 beta 3'e kadar çalışan sürüm

XCode7 b3'e kadar

Varlık adını daha uygun tekil olarak düzelttiğime dikkat edin.

Xcode 7.1'de Swift 2.0 için çalışan sürüm
(Xcode 7 beta 4 ve üzeri için çalışmalıdır)

Modüldeki "Mevcut Ürün Modülü" metnini silmeniz gerekiyor!

Xcode7 beta 3'ten

2.
Ayrıca dahil etmek için sık sık öneriye uymalısınız

@objc(Show)

sınıfının hemen üstünde.

Not : Xcode 7 beta 4 veya sonraki bir sürümünü kullanıyorsanız bu adım isteğe bağlıdır.

3.
Ayrıca , varsayılan olarak tam olacağı için, oluşturulan yönetilen nesneyi uygun sınıfa çevirdiğinizden emin olun NSManagedObject.

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

3
Teşekkürler! Önerilen adlandırma kuralı güncellemelerini yaptım ve 'Sınıf yüklenemiyor ...' hatasını düzeltmede hile yapan '@objc (Göster)' oldu. Çok takdir!
JimmyJammed

Merhaba @Mundi. Çok teşekkür ederim! Hala kaynağın nerede olduğunu hatırlıyor musun?
iamdavidlam

1
Örneğin bu soruya bakın . Orada neler olduğunu anlamak için yeterli bilgi var.
Mundi

4
Yeterince ilginç bir şekilde, kaldırmak zorunda kaldım @objc(MyClass)
Noel Baba

1
@Mundi, cevabınızı tekrar güncellemek isteyebilirsiniz. Khunshan'ın cevap güncellemesine bakın.
Suragch

76

SWIFT 2 / XCODE 7 Güncellemesi:

Bu sorun olup (aynı zamanda bu cevap benim 3 Nisan yorumunu bakınız) çözülmesi içinde Swift 2 ve XCode 7 Apple tarafından beta sürümü. Yani artık @objc(myEntity)Swift'de Mundi'nin yanıtladığı şekilde veya MyAppName.Sınıf adınızdan önce " " kullanmanız gerekmiyor . Çalışmayı bırakacak. Öyleyse bunları kaldırın, sadece DosyayaClass isim girin ve Modül olarak seçin ve alkışlayın!Current Working Module

Mevcut çalışma modülünün seçilmesi

Ancak @objc(myEntity)Swift'i kullananlar için (benim gibi), bunun yerine sorunsuz çalışan bu diğer çözümü kullanabilirsiniz.

Xcdatamodel'de doğru sınıfta. Şöyle görünmelidir:

Sınıfı belirleme

Hadi bakalım. Module.ClassSwift ve XCode 6'daki CoreData modelidir. Model Policy veya diğer CoreData öğelerinde Custom Policy sınıfını kullanırken de aynı prosedüre ihtiyacınız olacaktır . Bir not: Resimde, Ad ve Sınıf, Araba ve UygulamamAdı.Car olmalıdır (veya varlığınızın adı ne olursa olsun). İşte Userbir yazım hatası.


Bu çözümle ilgili sorun, otomatik olarak oluşturulan varlık sınıflarının artık düzgün çalışmamasıdır (modül adıyla yalnızca bir sınıf oluşturacaktır). Bakınız: NSManagedObject alt sınıfı oluşturma, düzgün şekilde üretilmiyor .
milos

NSManagedObject varlık sınıflarını oluşturduktan sonra çözümü uygulamanız gerekir. Muhtemelen bir xcode 6.xx hatası kaldırılacak.
khunshan

2
Evet, bu şüphesiz çözülecektir. Otomatik oluşturulan sınıflar @objc (<varlık denetçisine girilen sınıf adı>) ile süslenmiş olmalıdır, aksi takdirde Apple bunu başlangıçta gereksiz hale getirecektir.
milos

2
Hala bunu okuyan insanlar için. ' MyAppName.Car ' kullanmak benim için işe yaramadı, ' UygulamamAdı'nı kaldırdığımda işe yaradı. ' Bölüm. Yani sadece Carher iki alan için hile yaptı.
Gideon

1
Şampiyon sen !!!! let person = NSEntityDescription.insertNewObject (forEntityName: "Kişi", içine: bağlam) as! Kişi
Abhimanyu Rathore

36

Xcode 7'yi ve tamamen Swift'i kullanırken, aslında otomatik olarak oluşturulan alt sınıfımdan ( > ' den oluşturulmuş ) çıkarmak zorunda kaldım .@objc(MyClass)NSManagedObjectEditorCreate NSManagedObject Subclass...


4
Bu cevabı gönderdiğiniz için vay canına teşekkürler. Kafamı duvara vurmaya başlamak üzereydim.
Zia

Burada da aynı sorun - Bir hata gönderildi.
MirekE

Benim için de çalıştı. Kaldırmak zorunda kaldı. Tuhaf.
Kent

Deneylerime göre yanlış pozitif gibi görünüyor.
Mundi

Onu kaldırmam ve Mevcut Ürün Modülünü ayarlamam gerekiyordu, ancak o zaman işe yaradı
Oleg Sherman

13

Xcode 7 beta 2'de (ve 1'e inanıyorum), model yapılandırmasında FileModüle yeni bir yönetilen nesne türü ayarlanır Current Product Moduleve nesnenin sınıfı olarak yapılandırmada gösterilir .File.

Xcode 7'de "Mevcut Ürün Modülü" olarak ayarlanmış yönetilen nesne türü modülü

Modül ayarını boş olacak şekilde silme veya yapılandırmadaki sınıf adı yalnızca Fileeşdeğer eylemler olacak şekilde tam durağı kaldırma, her biri diğer değişikliğe neden olduğu için. Bu yapılandırmanın kaydedilmesi, açıklanan hatayı ortadan kaldıracaktır.

Yönetilen nesnenin modülü Xcode 7'de boş olarak ayarlandı


9

Xcode 6.1.1'de, temel varlık bir objc sınıfının (NSManagedObject) bir alt kümesi olduğu için @objc niteliğini eklemenize gerek yoktur (bkz. Swift Tipi Uyumluluğu . CoreData'da tam Module.Class adı gereklidir. Modüle dikkat edin) ad, Oluşturma Ayarları -> Paketleme -> Ürün Modülü Adı'nda ayarlanır. Varsayılan olarak bu, Hedefin adı olacak $ (PRODUCT_NAME: c99extidentifier) ​​olarak ayarlanır .


Evet! Bu modern cevaptır (xcode 6.3.2). Doğru paket adını kullanmak çok önemlidir. Benim durumumda, my-productdönüştü my_productve bu, Temel Veriler için tüm farkı yarattı.
SimplGy

5

XCode 7 ve Swift 2.0 sürümüyle, @objc (NameOfClass) eklemenize gerek yoktur, sadece "Veri Modeli Denetçisini Göster" sekmesinde varlık ayarlarını aşağıdaki gibi değiştirmeniz yeterlidir -

Ad - "Varlık Adınız"

Sınıf - "Varlık Adınız"

Modül - "Mevcut Ürün Modülü"

görüntü açıklamasını buraya girin

Varlık sınıfı dosyası için Kod (Kodumda Varlık Ailedir) gibi olacaktır -

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

Bu örnek uygulamamda xCode 7.0 + swift 2.0 ile iyi çalışıyor


3

PRODUCT_MODULE_NAMEÜrün modülü adınızla değiştirmeyi unutmayınız .

Yeni bir varlık oluşturulduğunda, Veri Modeli Denetçisine (son sekme) gitmeniz ve PRODUCT_MODULE_NAMEmodül adınızla değiştirmeniz gerekir, aksi takdirde class not foundkalıcı mağaza koordinatörü oluşturulurken bir hataya neden olur.


2

Örneğin, dökümünüzü gerçekleştirirken Module.Class'ı da kullanmanız gerekir (en azından Xcode 6.3.2 ile): Modülünüzün (yani ürün adı) Yiyecek ve sınıfınızın Meyve olduğunu varsayarsak

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

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

Özet:

  • Veri Modeli Düzenleyicisinde varlığı tanımlarken modül adını dahil edin (Ad: Meyve, Sınıf: Yiyecek.Fruit)
  • Varlığa kodda (yani SWIFT) erişirken, onu Module.class (örn. Food.Fruit) ile yayınlayın.

Teşekkür ederim, ikinci nokta çok önemli. Yayınlarken "Module.Class" kullanmak zorunda kaldım.
Zoyt


1

Veri Modeli düzenleyicisindeki Varlık Sınıfı adını söz konusu sınıfa karşılık gelecek şekilde değiştirmek @objc(NameOfClass)ve sınıf bildiriminin hemen üzerindeki her NSManagedObject dosyasına eklemek , Birim Testi sırasında bu sorunu benim için çözdü.


0

Benim için işe yarayan şey (Xcode 7.4, Swift), <my actual class name>.<entity name> Varlık denetçisi 'Sınıf' kutusunda sınıf adını değiştiriyor .

Yönetilen nesne alt sınıfının başlatıcısı şuna benzer:

    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

Xcode 11.5 için: Codegen özelliği sınıf Tanımı ise ve xcdatamodel'de oluşturduğunuz varlık için bir öneri almıyorsanız. Xcode'dan çıkmayı ve projenizi yeniden açmayı deneyin. Benim için çalışıyor. Bu yanıt yalnızca öneri almıyorsanız, ancak dosyanız oluşturulmadıysa yukarıdaki yanıtlardan herhangi birini deneyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.