Di aplikasi Lion saya, saya memiliki model data ini:
Hubungan subitems
di dalam Item
diperintahkan .
Xcode 4.1 (build 4B110) telah menciptakan bagi saya file Item.h
, Item.m
, SubItem.h
dan SubItem.h
.
Berikut adalah konten (di-autogenerasi) dari Item.h
:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class SubItem;
@interface Item : NSManagedObject {
@private
}
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSOrderedSet *subitems;
@end
@interface Item (CoreDataGeneratedAccessors)
- (void)insertObject:(SubItem *)value inSubitemsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromSubitemsAtIndex:(NSUInteger)idx;
- (void)insertSubitems:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeSubitemsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInSubitemsAtIndex:(NSUInteger)idx withObject:(SubItem *)value;
- (void)replaceSubitemsAtIndexes:(NSIndexSet *)indexes withSubitems:(NSArray *)values;
- (void)addSubitemsObject:(SubItem *)value;
- (void)removeSubitemsObject:(SubItem *)value;
- (void)addSubitems:(NSOrderedSet *)values;
- (void)removeSubitems:(NSOrderedSet *)values;
@end
Dan di sini adalah konten (di-autogenerasi) dari Item.m
:
#import "Item.h"
#import "SubItem.h"
@implementation Item
@dynamic name;
@dynamic subitems;
@end
Seperti yang Anda lihat, kelas Item
menawarkan metode yang disebut addSubitemsObject:
. Sayangnya, ketika mencoba menggunakannya dengan cara ini:
Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";
SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];
[item addSubitemsObject:subItem];
kesalahan ini muncul:
2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet
Bisakah kamu membantuku?
Memperbarui:
Setelah hanya 1.787 hari sejak laporan bug saya, hari ini (1 Agustus 2016) Apple menulis ini kepada saya: "Harap verifikasi masalah ini dengan versi beta iOS 10 terbaru dan perbarui laporan bug Anda di bugreport.apple.com dengan hasil Anda." . Mari berharap ini adalah waktu yang tepat :)
mutableOrderedSetValueForKey:
)Jawaban:
Saya mereproduksi pengaturan Anda baik dengan model data Anda dan saya sendiri dengan nama yang berbeda. Saya mendapat kesalahan yang sama dalam kedua kasus.
Sepertinya ada bug dalam kode autogenerated Apple.
sumber
Saya setuju bahwa mungkin ada bug di sini. Saya telah memodifikasi implementasi add objek setter untuk ditambahkan dengan benar ke NSMutableOrderedSet.
Menugaskan ulang set ke self.subitems akan memastikan bahwa notifikasi Will / DidChangeValue dikirim.
sumber
Saya telah memutuskan untuk meningkatkan solusi dengan menerapkan semua metode yang diperlukan:
sumber
willChangeValueForKey:withSetMutation:usingObjects
, yang berhasil Anda hindari. Setelah itu, gunakan saja[[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values]
atau[[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values]
sesuai kebutuhan. Lihat jawaban saya untuk detailnya.Ya, ini jelas merupakan bug Data Inti. Saya menulis perbaikan berbasis ObjC-Runtime beberapa waktu lalu, tetapi pada saat itu saya pikir itu akan segera diperbaiki. Bagaimanapun, tidak ada keberuntungan, jadi saya mempostingnya di GitHub sebagai KCOrderedAccessorFix . Atasi masalah pada semua entitas Anda:
Satu entitas khususnya:
Atau hanya untuk satu hubungan:
sumber
- (BOOL)kc_needsOrderedSetAccessorFix;
atau sesuatu yang memeriksa versi Foundation / iOS.objc_msg_send
)Alih-alih membuat salinan, saya sarankan untuk menggunakan accessor di NSObject untuk mendapatkan akses ke NSMutableOrderedSet dari hubungan tersebut.
mis. Catatan Rilis Data Inti untuk iOS v5.0 lihat ini.
Dalam tes singkat itu berfungsi di aplikasi saya.
sumber
NSStringFromSelector(@selector(subitems))
:)Saya telah melacak bug. Itu terjadi pada
willChangeValueForKey:withSetMutation:usingObjects:
.Panggilan ini memicu serangkaian pemberitahuan yang mungkin sulit dilacak, dan tentu saja perubahan pada satu responden mungkin berdampak pada yang lain, yang saya curigai adalah alasan Apple tidak melakukan apa pun.
Namun, tidak apa-apa di Set dan satu-satunya operasi Set pada OrderedSet yang tidak berfungsi. Itu berarti hanya ada empat metode yang perlu diubah. Oleh karena itu, yang saya lakukan hanyalah mengonversi operasi Tetapkan ke operasi Array yang setara. Ini berfungsi dengan baik dan biaya overhead minimal (tapi perlu).
Pada tingkat kritis, solusi ini memang menderita satu kelemahan kritis; jika Anda menambahkan objek dan salah satu objek sudah ada, maka itu tidak ditambahkan atau dipindahkan ke belakang daftar yang dipesan (saya tidak tahu yang mana). Dalam kedua kasus tersebut, indeks pesanan yang diharapkan dari objek pada saat kami tiba
didChange
berbeda dari apa yang diantisipasi. Ini mungkin merusak beberapa aplikasi orang, tetapi itu tidak mempengaruhi saya, karena saya hanya pernah menambahkan objek baru atau saya mengkonfirmasi lokasi terakhir mereka sebelum saya menambahkannya.Tentu saja, ada solusi yang lebih mudah. itu adalah sebagai berikut;
sumber
Dokumen Apple To Many Relations mengatakan: Anda harus mengakses set proxy yang dapat berubah atau set memerintahkan menggunakan
Mengubah set ini akan menambah atau menghapus relasi ke objek terkelola Anda. Mengakses perangkat yang dapat diatur yang dapat diubah menggunakan accessor baik dengan [] atau. notasi salah dan akan gagal.
sumber
Menerima kesalahan yang sama, solusi @LeeIII bekerja untuk saya (terima kasih!). Saya sarankan sedikit memodifikasinya:
Isi dari
Item+category.m
:sumber
Jika Anda menggunakan mogenerator, maka alih-alih
cukup gunakan:
sumber
mogenerator
tetapi saya masih memiliki bug.Secara pribadi saya baru saja mengganti panggilan ke metode yang dihasilkan CoreData dengan panggilan langsung ke metode yang diuraikan dalam solusi lain oleh @Stephan:
Ini menghilangkan kebutuhan untuk kategori yang nantinya mungkin bertentangan dengan solusi dari Apple ke kode yang dihasilkan ketika bug diperbaiki.
Ini memiliki nilai tambah sebagai cara resmi untuk melakukannya!
sumber
addObject:
dipanggil dua kali?Tampaknya jika Anda menautkan orang tua dengan anak dengan mengatur orang tua ke anak dan bukan sebaliknya bekerja tanpa menabrak.
Jadi, jika Anda melakukannya:
dari pada
Itu harus bekerja, setidaknya itu berfungsi di iOS 7 dan tidak punya masalah dengan hubungan.
sumber
Saya memiliki masalah yang sama, tetapi hanya ketika saya mencoba sesuatu yang berbeda dengan apa yang telah saya lakukan. Saya tidak dapat melihat kode untuk subItem, tetapi saya akan menganggap bahwa ia memiliki tautan balik ke item. Mari kita sebut tautan penghormatan ini, "parentItem", maka solusi termudah adalah ini:
Efeknya adalah ia menggunakan kode apel sendiri dan sederhana serta bersih. Selain itu, set secara otomatis ditambahkan ke, dan semua pengamat diperbarui. Tidak masalah.
sumber
Saya baru saja tersinggung masalah ini, dan mengatasinya menggunakan implementasi yang jauh lebih sederhana daripada yang lain yang dijelaskan di sini. Saya hanya menggunakan metode yang tersedia
NSManagedObject
untuk berurusan dengan hubungan ketika tidak menggunakan subclass.Contoh implementasi untuk memasukkan entitas ke dalam
NSOrderedSet
hubungan akan terlihat seperti ini:Ini berfungsi dengan baik, dan itulah yang saya gunakan sebelum saya pindah ke
NSManagedObject
subclass.sumber
Masalah ini terjadi pada saya saat memigrasi proyek dari Objective-C ke Swift 2 dengan XCode 7 . Proyek itu dulu berfungsi, dan untuk alasan yang bagus: Saya menggunakan MOGenerator yang memiliki metode pengganti untuk memperbaiki bug ini. Tetapi tidak semua metode membutuhkan penggantian.
Jadi, inilah solusi lengkap dengan kelas contoh, sebanyak mungkin menggunakan pengakses default.
Katakanlah kita memiliki Daftar dengan Barang yang dipesan
Pertama kemenangan cepat jika Anda memiliki hubungan satu / ke-banyak, yang paling mudah adalah dengan hanya melakukan:
dari pada
Sekarang, jika itu bukan pilihan , inilah yang dapat Anda lakukan:
Tentu saja, jika Anda menggunakan Objective-C, Anda dapat melakukan hal yang persis sama karena di sinilah saya mendapatkan ide itu :)
sumber
Leelll, apakah Anda yakin bahwa setelah pengaturan kustom nilai NSMutableOrderedSet yang disimpan dalam set itu akan disimpan ke database dengan benar oleh CoreData? Saya tidak memeriksanya, tetapi sepertinya CoreData tidak tahu apa-apa tentang NSOrderedSet dan mengharapkan NSSet sebagai wadah hubungan yang banyak.
sumber
Saya pikir semua orang kehilangan masalah sebenarnya. Ini bukan dalam metode accessor tetapi pada kenyataan bahwa
NSOrderedSet
itu bukan subkelas dariNSSet
. Jadi ketika-interSectsSet:
dipanggil dengan set yang diatur sebagai argumen gagal.gagal dengan
*** -[NSSet intersectsSet:]: set argument is not an NSSet
Sepertinya perbaikannya adalah untuk mengubah implementasi dari operator yang diatur sehingga mereka menangani jenis secara transparan. Tidak ada alasan mengapa
-intersectsSet:
harus bekerja dengan set yang dipesan atau tidak teratur.Pengecualian terjadi dalam pemberitahuan perubahan. Agaknya dalam kode yang menangani hubungan terbalik. Karena itu hanya terjadi jika saya menetapkan hubungan terbalik.
Berikut ini adalah trik untuk saya
sumber
Saya baru saja mendapat masalah di Swift (Xcode 6.1.1).
Jawabannya adalah JANGAN KODE METODE APA PUN ATAU HAL-HAL TAMBAHAN di subclass NSManagedObject Anda. Saya pikir ini adalah kesalahan kompilator. Bug yang sangat aneh ..
Semoga ini bisa membantu ..
sumber
Saya memecahkan masalah ini dengan mengatur kebalikannya ke No Inverse, saya tidak tahu mengapa, Mungkin ada Bug Apple.
sumber
Saya memiliki situasi yang sama dengan item yang disebut "sinyal" alih-alih "subtitle". Solusi dengan tempset berfungsi dalam pengujian saya. Lebih jauh, saya punya masalah dengan metode removeSignals:. Override ini tampaknya berfungsi:
Jika ada cara yang lebih baik untuk melakukan ini, beri tahu saya. Input nilai saya tidak pernah lebih dari 10 -20 item sehingga kinerja tidak terlalu menjadi perhatian - namun tolong tunjukkan hal yang relevan.
Terima kasih,
Damien
sumber
Saya menemukan pertanyaan ini dengan googling untuk pesan kesalahan, dan hanya ingin menunjukkan bahwa saya mengalami kesalahan ini dengan cara yang sedikit berbeda (tidak menggunakan set yang dipesan). Ini bukan jawaban yang cukup untuk pertanyaan yang diberikan, tapi saya mempostingnya di sini kalau-kalau itu berguna bagi siapa pun yang menemukan pertanyaan ini saat mencari.
Saya menambahkan versi model baru, dan menambahkan beberapa hubungan ke model yang ada, dan mendefinisikan metode add * Object di file header sendiri. Ketika saya mencoba menelepon mereka, saya mendapatkan kesalahan di atas.
Setelah meninjau model-model saya, saya menyadari bahwa saya dengan bodohnya lupa untuk mencentang kotak "To-Many Relationship".
Jadi, jika Anda mengalami ini dan Anda tidak menggunakan set yang dipesan, periksa model Anda.
sumber
Saya menemukan perbaikan untuk bug ini yang berfungsi untuk saya. Saya hanya mengganti ini:
dengan ini:
sumber
Versi yang lebih baik dari jawaban yang benar di SWIFT
sumber
Saya menemukan menggunakan metode oleh LeeIII bekerja, tetapi pada profil menemukan itu sangat lambat. Butuh 15 detik untuk mem-parsing 1000 item. Mengomentari kode untuk menambahkan hubungan berubah 15 detik menjadi 2 detik.
Solusi saya (yang lebih cepat tetapi jauh lebih jelek) melibatkan pembuatan array yang bisa berubah-ubah kemudian menyalin ke set yang diperintahkan ketika semua parsing dilakukan. (Ini hanya kemenangan kinerja jika Anda akan menambahkan banyak hubungan).
Saya harap ini membantu orang lain!
sumber
Robert,
Saya setuju jawaban Anda akan berhasil untuk ini, tetapi perlu diingat bahwa sudah ada metode yang dibuat secara otomatis untuk menambahkan seluruh rangkaian nilai ke suatu hubungan. Dokumentasi Apple ( seperti yang terlihat di sini di bagian "Ke-banyak Hubungan" atau di sini di bawah bagian "Metode Aksesor Hubungan Ke Banyak Orang") menerapkannya seperti ini:
Anda bisa dengan mudah mengkompilasi set hubungan Anda di luar data inti dan kemudian menambahkan semuanya sekaligus menggunakan metode ini. Mungkin kurang jelek dari metode yang Anda sarankan;)
sumber
Saya cukup yakin akhirnya diperbaiki di iOS 10 beta 6 !
sumber