NSManagedObject öğesinin belirli alt sınıfı bulunamıyor


136

Core Data ile bir uygulama geliştirmeye çalışıyorum. Şunu kullanarak bir örnek oluşturduğumda:

let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

Günlükte bir uyarı var:

CoreData: warning: Unable to load class named 'User' for entity 'User'.  Class not found, using default NSManagedObject instead.

Nasıl düzeltebilirim?

Ve başka bir soru, NSManagedObject alt sınıfında bir örnek yöntemini nasıl tanımlayabilirim?

Düzenle:

Varlığın sınıfını aşağıdaki ekran görüntüsünde belirttik:

resim açıklamasını buraya girin


7
Varlık Sınıfı Adının önüne Çekirdek Veri Yönetimli Nesne Alt Sınıflarını Uygulama bölümünde belgelendiği gibi modül adı eklediniz mi?
Martin R

@MartinR: Sorumun güncellemesine bakın.
MsrButterfly

2
Sınıf "UygulamanızAdı.User" olmalıdır, belgelere bakın (önceki yorumumdaki bağlantı).
Martin R

@MartinR: Yardımınız için teşekkürler. İşe yarıyor.
MsrButterfly

En iyi şey bu sınıfları silmek ve yeniden oluşturmaktır. Bu benim için çalıştı
Abhishek

Yanıtlar:


220

Xcode 7 Güncellemesi (son): Modül adını sınıfa (Xcode 6'da olduğu gibi ve Xcode 7'nin erken beta sürümlerinde olduğu gibi ) eklemek artık gerekli değildir. Temel Veri Yönetimli Nesne Alt Sınıflarını Uygulayan Apple belgeleri buna göre güncellenmiştir.

Veri Modeli denetçisinde artık bir varlık için iki "Sınıf" ve "Modül" alanı vardır:

resim açıklamasını buraya girin

Varlık için Swift tarafından yönetilen bir nesne alt sınıfı oluşturduğunuzda, "Modül" alanı "Geçerli Ürün Modülü" olarak ayarlanır ve bu ayar ile örnek oluşturma hem ana uygulamada hem de birim testlerinde çalışır. Yönetilen bir nesne bir alt sınıfı, gereken değil işaretlenir @objc(classname)(bu gözlendi https://stackoverflow.com/a/31288029/1187415 ).

Alternatif olarak, "Modül" alanını boşaltabilir ("Hiçbiri" gösterecektir) ve yönetilen nesne alt sınıflarını ile işaretleyebilirsiniz @objc(classname)(bu https://stackoverflow.com/a/31287260/1187415 adresinde gözlemlenmiştir ).


Not: Bu yanıt ilk olarak Xcode 6 için yazılmıştır. Çeşitli Xcode 7 beta sürümlerinde bu sorunla ilgili bazı değişiklikler olmuştur. Birçok upvotes ve bağlantılarla kabul edilen bir cevap olduğu için, mevcut Xcode 7 son sürümünün durumunu özetlemeye çalıştım.

Hem kendi "araştırma" yaptım ve bu soru ve benzer soruya tüm cevapları okumak CoreData: uyarı: adlı sınıf yüklenemedi . Dolayısıyla, özel olarak listelemesem bile, atıf hepsine gider!


Xcode 6 için önceki yanıt :

Çekirdek Veri Yönetimli Nesne Alt Sınıflarının Uygulanmasında belgelendiği gibi , model varlık denetçisindeki Sınıf alanındaki varlıkların sınıf modülüne modülünüzün adını, örneğin "MyFirstSwiftApp.User" önekini eklemeniz gerekir.


2
Bu benim için çalışıyor. Soru: Temel veriler bir çerçeveye dahil edilirse, henüz gerçek bir uygulama olmadığından ManagedObject alt sınıf adının önüne nasıl ön ek uygulanır?
Allan Macatingrao

9
@Allan: Sen deneyebilirsiniz @objc(ClassName)Christer yanıtında önerilen yöntem.
Martin R

8
Çalışır, ancak varlık denetçisinde sınıf adını "APPNAME.User" olarak ayarladıktan sonra, model sınıflarını yeniden oluşturamıyorum: Xcode önekle karıştırılıyor gibi görünüyor ve adıyla bir dosya / sınıf oluşturuyor UYGULAMA İSMİ. Bir şey mi kaçırıyorum?
Pascal Bourque

1
Statik bir kitaplıkta temel verileri kullanırken Objective-C'de bu hatayı alırsanız ne olur?
George Taskos

1
@Suragch: Şimdi nihayet cevabı güncelledim, umarım her şeyin doğru olduğunu umuyorum.
Martin R

62

Tıpkı bir yan not gibi. aynı sorunu yaşadım. Ve tüm yapmak zorunda eklemek oldu @objc(ClassName)benim sınıf dosyasında.

Misal:

@objc(Person)
class Person { }

Ve bu benim sorunumu çözdü.


1
Objective-C'de bu şekilde typealias (<% ProjectName%>. Person -> Person) tanımladınız, bu yüzden çalışıyor.
MsrButterfly

Apple tamamen hızlı dönüştürmek unuttum gibi görünüyor .. bilmiyorum neden ama bu benim için oldukça nazikçe sabit
Jiří Zahálka

7
Bu, özellikle her hedefin CoreData modelini paylaştığı birden fazla hedefi olan bir projeniz varsa kullanışlıdır. Bu durumlarda, CD modelinin hedeflerden yalnızca biri için yararlı olmasını sağladığından, sınıf adının hedef tanımlayıcıya önekinin eklenmesi mümkün değildir.
djbp

@djbp Ve "neden olmasın?" Bilmek isterdim. Ad alanı kavramını seviyorum, ancak bu MacBook'umu pencereden dışarı atmak istememi sağladı (uzantıya sahip bir uygulamam var ve uzantıyı çalıştırırken bu sorunu vurdu). Bunu ad alanları ile yapmanın "doğru" bir yolu olmalı, bunu anlayamıyorum.
S'pht'Kr

Evet, bu, bir çalışma alanında paylaşılan veri modelleri ile çalışırken benim için çalıştı
naz

31

Bu soruya kabul edilen cevap, aynı sorunu çözmeme yardımcı oldu, ancak başkalarına yardımcı olacağını düşündüğüm bir uyarı aldım. Proje (modül) adınızın içinde boşluk varsa, boşluğu alt çizgiyle değiştirmeniz gerekir. Örneğin:

Varlık: MyEntity Sınıfı: My_App_Name.MyClass


Tam aradığım şey! Şerefe!
manosim

Sınıf adını AppName.ClassName ile ayarladığımızda, Xcode 9 onun noktasını kaldırır ve nokta olmadan bir sınıf oluşturur. Yani bu artık Xcode 9'da değil. *.
yo2bh


9

App vs Tests olarak çalışıyorsanız, sorun uygulamanın aradığı <appName>.<entityName>ve test olarak çalışırken olduğu gibi olabilir <appName>Tests.<entityName>. Şu anda kullandığım çözüm (Xcode 6.1) ClassCoreData kullanıcı arabirimindeki alanı doldurmak ve bunun yerine kodda yapmaktır.

Bu kod, Uygulama ve Testler olarak çalışıp çalışmadığınızı algılar ve doğru modül adını kullanıp managedObjectClassName.

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "StreakTests" : "Streak"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()

1
Çözümünüzü denedim ama "ölümcül hata: NSArray öğesi, gerçek sınıfına NSManagedObject döküm sırasında Swift Dizi Öğesi türü ile eşleşemedi" alıyorum. Aslında kendini döküm yaparken değil, bir for döngüsüne girmeye çalışırken.
Rodrigo Ruiz

1
Modelinizde herhangi bir kalıtım varsa bu örnek çalışmaz. Her yeni varlık için altententler üzerinde yineleme yapmanız ve bunları oluşturduğunuz yeni varlıklarla güncellemeniz gerekir.
Anton

8

Proje adınızda "Uygulamam" gibi bir kısa çizgi kullanıyorsanız "My_App.MyManagedObject" gibi kısa çizgi yerine bir alt çizgi kullanın. Genel olarak, xcdatamodeld dosyasının adına bakın ve bu addakiyle aynı öneki kullanın. Yani "My_App_1.xcdatamodeld", "My_App_1" önekini gerektirir


1
vay. Teşekkürler teşekkürler teşekkürler. Bu küçük
külçenin

5

Bu, aynı sorunu yaşayanlara yardımcı olabilir. Swift 2 ve Xcode 7 beta 2 ile öyleydim.

Solüsyon benim durumumda dışarı yorum yapmak oldu @objc(EntityName)içinde EntityName.swift.


3

Uygulamam iyi çalışıyor gibi görünse de aynı uyarıyı aldım. Sorun, son ekranda Düzenleyici> NSManagedObject Alt Sınıfı oluştururken, hiçbir Grup görüntülenmediği veya kontrol edilmediği varsayılan Grup konumunu kullandım, bu da alt sınıfı MyApp.xcodeproj'un bulunduğu üst Uygulam dizinine kaydetti.
Bunun yerine Grubu Uygulamam alt klasöründe olacak şekilde değiştirip Uygulamam hedefini kontrol ettiğimde uyarı ortadan kalktı.


2

Yukarıdaki cevaplar yardımcı oldu. Bu hızlı akıl sağlığı kontrolü size biraz zaman kazandırabilir. Proje> Aşama Oluştur> Kaynakları Derle'ye gidin ve "-" düğmesiyle xcdatamodeld'inizi ve model dosyalarınızı kaldırın ve hemen "+" düğmesiyle ekleyin. Yeniden oluştur - bu onunla ilgilenebilir.


2

Bu arada bir önek olarak eklediklerinize dikkat edin: Uygulamam "ABC-def" olarak adlandırılır ve Xcode "-" ifadesini "_" biçimine dönüştürmüştür.

Güvende olmak için bulucuya bakın, proje dosyalarınızı bulun ve veri modeliniz için ne dediğini görün (örneğin "ABC_def.xcdatamodeld") ve orada yazılanları TAMAMEN kullanın !!!


1

Yukarıdaki cevaplar Objective-C ile bağlantılı farklı sorunları çözmeme yardımcı oldu (belki birine yardımcı olacaktır):

Varlık adlarını yeniden düzenlediyseniz, "Yardımcı Programlar Paneli" nde de "Sınıf" ı değiştirmeyi unutmayın.


0

Yukarıdaki cevaplar bana yardımcı oldu ama bu birine yardımcı olabilir. Benim gibi onları yaptıysanız ve hala sorun yaşıyorsanız, sadece 'projenizi temizlemeyi' unutmayın. XCode8 için, Ürün> Temiz. Sonra tekrar çalıştırın.


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.