Poke links to see the final version
Original link
Tomasz Szulc
Original Date: 2015/08/06
Translator: mmoaay; proofreading: numbbbbb; Final: Shanks
The Swift 2 in Xcode 7 Beta 5 has another feature: When using a one-to-many relationship, we can @NSManaged
declare the automatic generation method.
This technique is very useful. Suppose you have one Library
and more Book
entity objects. Library
and books
is a one-to-many relationship. Then use the latest Xcode and you @NSManaged
can Library
declare the auto-generated method within the entity object (manually).
Just like this:
class Span class= "Hljs-type" >library : nsmanagedobject {@ Nsmanaged func addbooksobject (book : book ) @nsmanaged func removebooksobject (book : book ) @nsmanaged func addbooks (books : Span class= "Hljs-type" >set <book >) @ Nsmanaged func removebooks (books : set <book >) }
God, this way of realization is so elegant! Just a few days ago I had to write these methods from scratch.
But I found a problem. We can certainly declare methods like this, but the key to the problem is how to generate them anywhere and put them into the entity+coredataproperties.swift file? These methods are inherited when generating objective-c subclasses, even in Swift projects. However, when you generate the Swift language-these methods are gone! See rdar://22177139 for details.
The following code is the entity class generated by objective-c
@interface Library (CoreDataGeneratedAccessors)- (void)addBooksObject:(Book *)value;- (void)removeBooksObject:(Book *)value;- (void)addBooks:(NSSet<Book *> *)values;- (void)removeBooks:(NSSet<Book *> *)values;@end
If you mark a relationship as ordered, you need to declare more methods manually
- (void) InsertObject: (book *) value Inbooksatindex: (Nsuinteger) idx;-(void) Removeobjectfrombooksatindex: (Nsuinteger) idx;-(void) Insertbooks: (Nsarray<book *> *) value atindexes: (Nsindexset *) indexes;-(void) Removebooksatindexes: (Nsindexset *) indexes;-(void) Replaceobjectinbooksatindex: (nsuinteger) idx withobject: (book *) value;-(void) Replacebooksatindexes: (Nsindexset *) Indexes Withbooks: (Nsarray<book *> *) values;-(void) Addbooksobject: (Book *) value;-(void) Removebooksobject: (Book *) value;-(void) Addbooks: (Nsorderedset<book *> *) values;-(void) Removebooks: (nsorderedset<book *> *) values;
This is a good way to write trouble. Hope they fix this problem as soon as possible:)
Another issue waiting for Apple to fix is an ordered one-to-many relationship and its auto-generated method. This problem has existed for a long time. But do not know if there is a corresponding error report. I think this problem occurs when Core Data and the following method are first released. Let's say we want to Library
add someBook
let ctx = self.managedObjectContextlet library = NSEntityDescription.insertNewObjectForEntityForName("Library"inManagedObjectContext: ctx) as! Librarylet book1 = NSEntityDescription.insertNewObjectForEntityForName("Book"inManagedObjectContext: ctx) as! Booklibrary.addBooksObject(book1)
The result is simply not working.
-- ,- . at: -:18.541newnsmanagedexample[54727:3677632] * * * * terminating app Due toUncaughtException ' Nsinvalidargumentexception ', Reason:' * * * *-[nsset Intersectsset:]: Set argument is not a nsset 'First throw call stack: (0Corefoundation0x00ea83b4__exceptionpreprocess + the 1LIBOBJC. A.dylib0X005CDE02Objc_exception_throw + - 2Corefoundation0x00dfc574-[nsset Intersectsset:] +260 3Foundation0x00214756Nskeyvaluewillchangebysetmutation +153 4Foundation0x0017c4c7Nskeyvaluewillchange +394 5Foundation0x0021466a-[nsobject (nskeyvalueobservernotification) willChangeValueForKey:withSetMutation:usingObjects:] +630 6CoreData0x00a981c6_sharedimpl_addobjecttoset_core +182 7CoreData0x00a99189__generateaccessor_block_invoke_2 + A 8Newnsmanagedexample0x000f0e80_tfc19newnsmanagedexample11appdelegate11applicationfs0_ FTCSO13UIAPPLICATION29DIDFINISHLAUNCHINGWITHOPTIONSGSQGVSS10DICTIONARYCSO8NSOBJECTPSS9ANYOBJECT____SB +720 9Newnsmanagedexample0x000f10c7_ttofc19newnsmanagedexample11appdelegate11applicationfs0_ FTCSO13UIAPPLICATION29DIDFINISHLAUNCHINGWITHOPTIONSGSQGVSS10DICTIONARYCSO8NSOBJECTPSS9ANYOBJECT____SB +199 TenUIKit0x0122e1c6-[uiapplication _handledelegatecallbackswithoptions:issuspended:restorestate:] +337 OneUIKit0x0122f56c-[uiapplication _callinitializationdelegatesformainscene:transitioncontext:] +3727 AUIKit0x01236929-[uiapplication _runwithmainscene:transitioncontext:completion:] +1976 -UIKit0x01259af6__84-[uiapplication _handleapplicationactivationwithscene:transitioncontext:completion:]_block_invoke3142 + the -UIKit0X012336A6-[uiapplication Workspacedidendtransaction:] +163 theFrontboardservices0X03FF9CCC__37-[fbsworkspace clientendtransaction:]_block_invoke_2 + in -Frontboardservices0X03FF97A3__40-[fbsworkspace _performdelegatecallout:]_block_invoke + Wu -Frontboardservices0X040171CB-[fbsserialqueue _performnext] +184 -Frontboardservices0x04017602-[fbsserialqueue _performnextfromrunloopsource] + the +Frontboardservices0x040168feFbsserialqueuerunloopsourcehandler + - -Corefoundation0X00DC27AF__cfrunloop_is_calling_out_to_a_source0_perform_function__ + the +Corefoundation0x00db843b__cfrunloopdosources0 +523 ACorefoundation0x00db7858__cfrunlooprun +1032 atCorefoundation0x00db7196Cfrunlooprunspecific +470 -Corefoundation0x00db6fabCfrunloopruninmode +123 -UIKit0x01232f8f-[uiapplication _run] +540 -UIKit0x01238724Uiapplicationmain + the -Newnsmanagedexample0X000F24DCMain + $ -Libdyld.dylib0x039afa21Start +1) libc++abi.dylib:terminating withUncaughtException of type nsexception
The only solution to this problem is to re-implement those methods.
For more details see rdar://22177512--hope they will fix the problem soon.
Swift 2: You can use the @NSManage tag to automatically generate a method