i have realm model stores time line (i making video editing app) , quite crushes on accessing it's rmarray property. app shipped , haven't experienced myself crushlytics notifies me crash quite oftenly. here crash log:
fatal exception: rlmexception object has been deleted or invalidated. thread : fatal exception: rlmexception 0 corefoundation 0x2614d45f __exceptionpreprocess + 126 1 libobjc.a.dylib 0x3407ec8b objc_exception_throw + 38 2 videoeditor 0x00293919 rlmgetarray(rlmobjectbase*, unsigned int, nsstring*) (rlmrealm_private.hpp:38) 3 videoeditor 0x0018a1b4 videoeditor.rlmproject.settimelinemodel (videoeditor.rlmproject)(videoeditor.timelinemodel, beginwritetransaction : swift.bool) -> () (realmmodels.swift:147) 4 videoeditor 0x0025eb9c videoeditor.videoeditorapi.saveproject (videoeditor.videoeditorapi)(swift.optional<videoeditor.iproject>, timeline : videoeditor.timelinemodel, name : swift.string, filterid : swift.int, image : objectivec.uiimage) -> swift.implicitlyunwrappedoptional<videoeditor.iproject> (videoeditorapi.swift:42) 5 videoeditor 0x00164754 @objc videoeditor.projecteditorviewcontroller.saveproject (videoeditor.projecteditorviewcontroller)(swift.implicitlyunwrappedoptional<objectivec.nsnotification>) -> () (projecteditorviewcontroller.swift:514) 6 corefoundation 0x26105e31 __cfnotificationcenter_is_calling_out_to_an_observer__ + 12 7 corefoundation 0x260616cd _cfxnotificationpost + 1784 8 foundation 0x26db7dd9 -[nsnotificationcenter postnotificationname:object:userinfo:] + 72 9 uikit 0x296cae2d -[uiapplication _deactivateforreason:notify:] + 528 10 uikit 0x298d2dd7 -[uiapplication _handlenonlaunchspecificactions:forscene:withtransitioncontext:] + 1846 11 uikit 0x298caafd -[uiapplication workspace:didreceiveactions:] + 80 12 frontboardservices 0x2ca180a9 __31-[fbsserialqueue performasync:]_block_invoke + 12 13 corefoundation 0x26113fe5 __cfrunloop_is_calling_out_to_a_block__ + 12 14 corefoundation 0x261132a9 __cfrunloopdoblocks + 216 15 corefoundation 0x26111de3 __cfrunlooprun + 1714 16 corefoundation 0x2605f3b1 cfrunlooprunspecific + 476 17 corefoundation 0x2605f1c3 cfrunloopruninmode + 106 18 graphicsservices 0x2d5bf201 gseventrunmodal + 136 19 uikit 0x296c943d uiapplicationmain + 1440 20 merryvideoeditor 0x0028c88f main (main.m:16) 21 libdyld.dylib 0x3460aaaf start + 2 here rlmproject code:
protocol iproject{ var name: string { set } var filterid: int { set } var filterintensity: cgfloat { set } /// duration in seconds var duration: int { set } var datecreated: nsdate { } func settimelinemodel(timeline: timelinemodel, beginwritetransaction: bool) // should done projectimporter func gettimelinemodel() -> timelinemodel var videoassets: rlmarray { } var soundtracks: rlmarray { } } class rlmproject: rlmobject, iproject, printable { dynamic var videoassets: rlmarray = rlmarray(objectclassname: rlmmediaasset.classname()) dynamic var soundtracks: rlmarray = rlmarray(objectclassname: rlmmediaasset.classname()) dynamic var name: string = "" dynamic var filterid: int = 0 dynamic var filterintensity: cgfloat = 1 dynamic var duration: int = 0 dynamic var datecreated: nsdate = nsdate() dynamic var idvalue: int = 0 func settimelinemodel(timeline: timelinemodel, beginwritetransaction: bool = true) { func updatearray(array: rlmarray, withassetsarray assetsarray: [mediaasset], type: mediatype){ array.removeallobjects() asset in assetsarray{ let model = rlmmediaasset() model.setmediaasset(asset) model.settype(type) array.addobject(model) rlmrealm.defaultrealm().addobject(model) } } if beginwritetransaction { rlmrealm.defaultrealm().beginwritetransaction() } if videoassets.invalidated { videoassets = rlmarray(objectclassname: rlmmediaasset.classname()) } if soundtracks.invalidated { soundtracks = rlmarray(objectclassname: rlmmediaasset.classname()) } updatearray(videoassets, withassetsarray: timeline.videoassets, .video) updatearray(soundtracks, withassetsarray: timeline.soundtracks, .soundtrack) duration = int(cmtimegetseconds(timeline.totalduration)) datecreated = nsdate() if beginwritetransaction { rlmrealm.defaultrealm().commitwritetransaction() } } func gettimelinemodel() -> timelinemodel { let timeline = timelinemodel() timeline.videoassets = videoassets.map { ($0 rlmmediaasset).getmediaasset() } timeline.soundtracks = soundtracks.map { ($0 rlmmediaasset).getmediaasset() } return timeline } } extension rlmarray { func map<u>(transform: (rlmobject) -> u) -> [u]{ var array: [u] = [] object in self{ array.append(transform(object)) } return array } } does has idea wrong code?
when rlmproject invalidated, won't possible check videoassets.invalidated or soundtracks.invalidated, why stack trace shows uncaught exception being thrown in rlmgetarray.
this implies object has been deleted realm before call settimelinemodel. please realm.deleteobject(_:) in code see might happening.
finally, few general tips make code little safer , simpler:
instead of rlmrealm.defaultrealm() everywhere inside rlmobject, should use realm property. way, if decide change location of realm @ point, code inside rlmobject continue work.
also, rather create extension on rlmarray add map, use swift's free map function.
map(videoassets) { ($0 rlmmediaasset).getmediaasset() }
Comments
Post a Comment