ios - Extremely Odd Crash When saving a transformable NSAttributedString into Core Data -
i have project using core data. has note object has 1 transformable attribute called content. storing nsattributedstring property. property saves fine first save, when try create second note object, app crashes.
here code use save:
- (ibaction)save:(id)sender { note* newnote = [nsentitydescription insertnewobjectforentityforname:@"note" inmanagedobjectcontext:[self managedobjectcontext]]; nsattributedstring* string = [[self textview]attributedtext]; [newnote setcontent:string]; nsarray* tokens = [[self tokenfield]tokens]; nserror* error = nil; if (![[self managedobjectcontext]save:&error]) { nslog(@"error saving %@",[error localizeddescription]); } [[self navigationcontroller]popviewcontrolleranimated:yes]; } again code saves no problem when there no objects in persistent store.
when attempt save new object (in non empty store:) exception thrown first (i have break point set exceptions) -[nsconcretemutableattributedstring compare:]: unrecognized selector sent instance 0x1759e8b0
then when continue, this:
2013-07-18 10:17:39.011 meta[2417:60b] coredata: error: serious application error. exception caught during core data change processing. bug within observer of nsmanagedobjectcontextobjectsdidchangenotification. -[nsconcretemutableattributedstring compare:]: unrecognized selector sent instance 0x1759e8b0 userinfo (null) 2013-07-18 10:17:39.014 meta[2417:60b] *** terminating app due uncaught exception 'nsinvalidargumentexception', reason: '-[nsconcretemutableattributedstring compare:]: unrecognized selector sent instance 0x1759e8b0'
i using nsmanagedobject subclass implemented follows:
@interface note : nsmanagedobject @property (nonatomic, strong) id content; @end again content attempting store attributed string
i have tried using default nsvaluetransformer , own subclass. both cause same problem.
edit: here implementation of value transformer:
#import "attributedstringvaluetransformer.h" @implementation attributedstringvaluetransformer +(class)transformedvalueclass { return [nsattributedstring class]; } +(void)initialize { [nsvaluetransformer setvaluetransformer:[[self alloc]init] forname:@"nsattributedstringvaluetransformer"]; } +(bool)allowsreversetransformation { return yes; } -(nsdata*)transformedvalue:(nsattributedstring*)value { nsdata* stringasdata = [nskeyedarchiver archiveddatawithrootobject:value]; return stringasdata; } -(nsattributedstring*)reversetransformedvalue:(nsdata*)value { nsattributedstring* string = [nskeyedunarchiver unarchiveobjectwithdata:value]; return string; } 
edit: here backtrace:
(lldb) bt * thread #1: tid = 0x5d2ef, 0x39a3d688 libobjc.a.dylib`objc_exception_throw, queue = 'com.apple.main-thread, stop reason = breakpoint 1.1 frame #0: 0x39a3d688 libobjc.a.dylib`objc_exception_throw frame #1: 0x2f958fa2 corefoundation`-[nsobject(nsobject) doesnotrecognizeselector:] + 202 frame #2: 0x2f95787a corefoundation`___forwarding___ + 706 frame #3: 0x2f8a5528 corefoundation`__forwarding_prep_0___ + 24 frame #4: 0x302a5d48 foundation`_nscompareobject + 32 frame #5: 0x3034fe7e foundation`-[nssortdescriptor compareobject:toobject:] + 270 frame #6: 0x2f79e5f4 coredata`+[nsfetchedresultscontroller(privatemethods) _insertindexforobject:inarray:lowidx:highidx:sortdescriptors:] + 216 frame #7: 0x2f79ada6 coredata`-[nsfetchedresultscontroller(privatemethods) _postprocessinsertedobjects:] + 514 frame #8: 0x2f79c842 coredata`-[nsfetchedresultscontroller(privatemethods) _managedobjectcontextdidchange:] + 1898 frame #9: 0x2f89c836 corefoundation`_cfxnotificationpost + 1718 frame #10: 0x302a13b0 foundation`-[nsnotificationcenter postnotificationname:object:userinfo:] + 76 frame #11: 0x2f72280a coredata`-[nsmanagedobjectcontext(_nsinternalnotificationhandling) _postobjectsdidchangenotificationwithuserinfo:] + 78 frame #12: 0x2f721b0a coredata`-[nsmanagedobjectcontext(_nsinternalchangeprocessing) _createandpostchangenotification:withdeletions:withupdates:withrefreshes:] + 298 frame #13: 0x2f6a0af6 coredata`-[nsmanagedobjectcontext(_nsinternalchangeprocessing) _processrecentchanges:] + 2346 frame #14: 0x2f7159ba coredata`-[nsmanagedobjectcontext save:] + 190 frame #15: 0x00106f82 meta`-[newnoteviewcontroller save:](self=0x15dd2030, _cmd=0x325ba35a, sender=0x15dc5a70) + 918 @ newnoteviewcontroller.m:176 frame #16: 0x320482a2 uikit`-[uiapplication sendaction:to:from:forevent:] + 90 frame #17: 0x32048330 uikit`-[uibarbuttonitem(uiinternal) _sendaction:withevent:] + 120 frame #18: 0x320482a2 uikit`-[uiapplication sendaction:to:from:forevent:] + 90 frame #19: 0x32048242 uikit`-[uiapplication sendaction:totarget:fromsender:forevent:] + 30 frame #20: 0x32048220 uikit`-[uicontrol sendaction:to:forevent:] + 44 frame #21: 0x3217cfce uikit`-[uicontrol _sendactionsforevents:withevent:] + 374 frame #22: 0x32048036 uikit`-[uicontrol touchesended:withevent:] + 590 frame #23: 0x31f830e0 uikit`-[uiwindow _sendtouchesforevent:] + 528 frame #24: 0x31f718f0 uikit`-[uiapplication sendevent:] + 196 frame #25: 0x32114406 uikit`_uiapplicationhandlehidevent + 6262 frame #26: 0x306765ce iokit`__iohideventsystemclientqueuecallback + 222 frame #27: 0x2f911f04 corefoundation`__cfmachportperform + 136 frame #28: 0x2f91d206 corefoundation`__cfrunloop_is_calling_out_to_a_source1_perform_function__ + 34 frame #29: 0x2f91d1a2 corefoundation`__cfrunloopdosource1 + 346 frame #30: 0x2f91b966 corefoundation`__cfrunlooprun + 1398 frame #31: 0x2f892446 corefoundation`cfrunlooprunspecific + 522 frame #32: 0x2f89222a corefoundation`cfrunloopruninmode + 106 frame #33: 0x343f06da graphicsservices`gseventrunmodal + 138 frame #34: 0x31fbae00 uikit`uiapplicationmain + 1136 frame #35: 0x00105374 meta`main(argc=1, argv=0x27d07d1c) + 116 @ main.m:16
found it:
* thread #1: tid = 0x5d2ef, 0x39a3d688 libobjc.a.dylib`objc_exception_throw, queue = 'com.apple.main-thread, stop reason = breakpoint 1.1 frame #0: 0x39a3d688 libobjc.a.dylib`objc_exception_throw frame #1: 0x2f958fa2 corefoundation`-[nsobject(nsobject) doesnotrecognizeselector:] + 202 frame #2: 0x2f95787a corefoundation`___forwarding___ + 706 frame #3: 0x2f8a5528 corefoundation`__forwarding_prep_0___ + 24 frame #4: 0x302a5d48 foundation`_nscompareobject + 32 frame #5: 0x3034fe7e foundation`-[nssortdescriptor compareobject:toobject:] + 270** frame #6: 0x2f79e5f4 coredata`+[nsfetchedresultscontroller(privatemethods) _insertindexforobject:inarray:lowidx:highidx:sortdescriptors:] + 216 frame #7: 0x2f79ada6 coredata`-[nsfetchedresultscontroller(privatemethods) _postprocessinsertedobjects:] + 514 frame #8: 0x2f79c842 coredata`-[nsfetchedresultscontroller(privatemethods) _managedobjectcontextdidchange:] + 1898 as save happened, fetched results controller started update tableview (which on presenting view controller).
i have tableview controller subclass use easy setup takes sort descriptor key (as string) , internally turns array , sets fetch request.
[self setsortdescriptorkey:@"content"]; content transformable attribute in data model (transforms nsattributedstring). normal string, needed store attribute data well. after changing it, frc sending compare it. fixed changing sort descriptor key:
[self setsortdescriptorkey:@"content.string"];
Comments
Post a Comment