ios - App crash on sendEvent method -


when rotate app twice after selecting few items, crashes. have overridden sendevent method , that's debugger stops. when try print event type, shows me weird (i think it's memory location doesn't exist):

(lldb) print event.type (uieventtype) $r10 = <invalid> (0xff) 

somehow think related how handle rotation. have master-detail style application, uses different type of navigation pad-landscape, pad-portrait , phone. have created class named navigationflowcontroller handles navigational events , sets views accordingly. on rotation, breaks view trees , recomposes them correct navigation

func changeviewhierarchyfordevideandorientation(neworientation:uiinterfaceorientation? = nil){     print("ma - calling master layout method")      uiapplication.mydelegate().window?.frame = uiscreen.mainscreen().bounds      let idiom = uidevice.currentdevice().userinterfaceidiom     var orientation:uiinterfaceorientation!     if let no = neworientation{         orientation = no     }else{         orientation = uiapplication.sharedapplication().statusbarorientation     }      print("ma - breaking view tree...")      breakupformerviewtree([sidebarviewcontroller, listviewcontroller, detailviewcontroller, loginviewcontroller])      print("ma - start init navbackbone")      initnavbackbonecontrollers()      guard let _ = uiapplication.mydelegate().currentuser else {         if idiom == uiuserinterfaceidiom.phone{             currentstate = appstate.phone         }else if idiom == uiuserinterfaceidiom.pad && uiinterfaceorientationislandscape(orientation){             currentstate = appstate.pad_landscape         }else if idiom == uiuserinterfaceidiom.pad && uiinterfaceorientationisportrait(orientation){             currentstate = appstate.pad_portrait         }          print("ma - current user nil - resetting")          mainviewcontroller.addchildviewcontroller(loginviewcontroller)          return     }      if idiom == uiuserinterfaceidiom.phone{         currentstate = appstate.phone          leftnavigationcontroller?.viewcontrollers = [listviewcontroller]          slideviewcontroller?.rearviewcontroller = sidebarviewcontroller         slideviewcontroller?.frontviewcontroller = leftnavigationcontroller          slideviewcontroller?.rearviewrevealwidth = 267;          mainviewcontroller.addchildviewcontroller(slideviewcontroller!)     }else if idiom == uiuserinterfaceidiom.pad && uiinterfaceorientationislandscape(orientation){         currentstate = appstate.pad_landscape          leftnavigationcontroller!.viewcontrollers = [sidebarviewcontroller, listviewcontroller]         rightnavigationcontroller!.viewcontrollers = [detailviewcontroller]         detailviewcontroller.navigationitem.leftbarbuttonitems = []         detailviewcontroller.initlayout()          print("ma - init split view controller vcs")          splitviewcontroller!.viewcontrollers = [leftnavigationcontroller!, rightnavigationcontroller!]          mainviewcontroller.addchildviewcontroller(splitviewcontroller!)      }else if idiom == uiuserinterfaceidiom.pad && uiinterfaceorientationisportrait(orientation){         currentstate = appstate.pad_portrait          leftnavigationcontroller!.pushviewcontroller(sidebarviewcontroller, animated: false)         leftnavigationcontroller!.pushviewcontroller(listviewcontroller, animated: false)          rightnavigationcontroller!.pushviewcontroller(detailviewcontroller, animated: false)         rightnavigationcontroller?.setnavigationbarhidden(false, animated: false)          slideviewcontroller!.rearviewcontroller = leftnavigationcontroller         slideviewcontroller!.frontviewcontroller = rightnavigationcontroller          detailviewcontroller.navigationitem.leftbarbuttonitem = uibarbuttonitem(title: "< documenten", style: uibarbuttonitemstyle.bordered, target: slideviewcontroller, action: "revealtoggle:")         detailviewcontroller.initlayout()         slideviewcontroller!.rearviewrevealwidth = 350;          mainviewcontroller.addchildviewcontroller(slideviewcontroller!)     }  }  func breakupformerviewtree(vcs:[uiviewcontroller?]){     vc in vcs{         if let vcunwrapped = vc, _ = vcunwrapped.parentviewcontroller {             vcunwrapped.removefromparentviewcontroller()             vcunwrapped.view.removefromsuperview()         }     } }  func initnavbackbonecontrollers(){     leftnavigationcontroller = uinavigationcontroller()     leftnavigationcontroller?.navigationbar.bartintcolor = uicolor(red: 0.25, green: 0.25, blue: 0.25, alpha: 1.0)     leftnavigationcontroller?.navigationbar.tintcolor = uicolor.whitecolor()     leftnavigationcontroller?.navigationbar.titletextattributes = [nsforegroundcolorattributename: uicolor.whitecolor()]     leftnavigationcontroller?.navigationbar.translucent = false      rightnavigationcontroller = uinavigationcontroller()     rightnavigationcontroller?.navigationbar.bartintcolor = uicolor(red: 0.25, green: 0.25, blue: 0.25, alpha: 1.0)     rightnavigationcontroller?.navigationbar.tintcolor = uicolor.whitecolor()     rightnavigationcontroller?.navigationbar.titletextattributes = [nsforegroundcolorattributename: uicolor.whitecolor()]     rightnavigationcontroller?.navigationbar.translucent = false      slideviewcontroller = swrevealviewcontroller()     slideviewcontroller?.rearviewrevealoverdraw = 0;     slideviewcontroller?.bouncebackonoverdraw = false;     slideviewcontroller?.stabledragonoverdraw = true;     slideviewcontroller?.delegate = self      if uidevice.currentdevice().userinterfaceidiom == uiuserinterfaceidiom.pad{         splitviewcontroller = uisplitviewcontroller()     } } 

edit (in response justin's questions):

1) i've experienced crash on ios8 ipad simulators.

2) fresh start, if select 6-7 items , rotate twice, crashes. can select item, rotate few times, select more , keep rotating , @ point crash.

3) when item selected, following code executed:

func tableview(tableview: uitableview, didselectrowatindexpath indexpath: nsindexpath) {     let document = getinfoforsection(indexpath.section).documents[indexpath.item]     if document.canopen{         opendocument(document)          datamanager.sharedinstance.getdocument(document.uri, after: {             (document:document?) -> () in             if let documentunwrapped = document{                 let detailvc = navigationflowcontroller.sharedinstance.detailviewcontroller;                 if detailvc.document?.uri == documentunwrapped.uri{                     navigationflowcontroller.sharedinstance.detailviewcontroller.documentupdated(documentunwrapped)                 }             }         })     } } 

and in detail view controller:

func initlayout(){     if viewforcard == nil{         // views not yet initialized, happens when initlayout if called document setter before view has been loaded         // return, layouting done on viewdidload correct document instead         return     }      self.navigationitem.rightbarbuttonitems = []      if document == nil{         // removed code handles no document selected         ...         return     }      heightforcard.constant = navigationflowcontroller.sharedinstance.currentstate == appstate.phone ? card_height_phone : card_height_tablet      viewforcard.hidden = false     removeallsubviews(viewforcard)     removeallsubviews(viewfordetails)      viewfordetails.translatesautoresizingmaskintoconstraints = false      self.metavc?.document = document     //self.documentvc?.document = document     self.navigationitem.rightbarbuttonitems = []      downloaddocumentifneeded()      if navigationflowcontroller.sharedinstance.currentstate == appstate.pad_landscape || navigationflowcontroller.sharedinstance.currentstate == appstate.pad_portrait{         self.viewfordetails.backgroundcolor = document?.senderstyling?.color          addchildviewcontroller(self.metavc!)         addchildviewcontroller(self.documentvc!)          let metaview = self.metavc!.view         let documentview:uiview = self.documentvc!.view          viewfordetails.addsubview(metaview)         viewfordetails.addsubview(documentview)          // whole lot of layouting code removed         ...                      let doubletap = uitapgesturerecognizer(target: self, action: "togglezoom")         documentvc!.view.addgesturerecognizer(doubletap)      }else{         // phone version code removed         ...     }    } 

edit2:

func downloaddocumentifneeded(){     var tmppath:nsurl?     if let url = document?.contenturl{         let directoryurl = nsfilemanager.defaultmanager().urlsfordirectory(.documentdirectory, indomains: .userdomainmask)[0]          if let docname = self.document?.name,             safename = disallowedcharacters?.stringbyreplacingmatchesinstring(docname, options: [], range: nsmakerange(0, docname.characters.count), withtemplate: "-"){                 tmppath = directoryurl.urlbyappendingpathcomponent("\(safename)_\(detailviewcontroller.dateformatter.stringfromdate(self.document!.creationdate!)).pdf")          }           if let urlstring = tmppath?.path{             if nsfilemanager.defaultmanager().fileexistsatpath(urlstring) {                 // file there, load                 loaddocumentinwebview(tmppath!)             }else{                 // download file                 let destination: (nsurl, nshttpurlresponse) -> (nsurl) = {                     (temporaryurl, response) in                      if let path = tmppath{                         return path                     }                      return temporaryurl                 }                  download(.get, urlstring: url, destination: destination).response {                     (request, response, data, error) in                      if error != nil && error?.code != 516{                         toastview.showtoastinparentview(self.view, withtext: "an error has occurred while loading document", withduaration: 10)                     }else if let pathunwrapped = tmppath {                         self.loaddocumentinwebview(pathunwrapped)                     }                 }             }         }     } }  func loaddocumentinwebview(path:nsurl){     if self.navigationitem.rightbarbuttonitems == nil{         self.navigationitem.rightbarbuttonitems = []     }      self.documentvc?.finalpath = path      let shareitem = uibarbuttonitem(barbuttonsystemitem: uibarbuttonsystemitem.action, target: self, action: "share")     shareitem.tag = share_item_tag      addnavitem(shareitem)  }  func addnavitem(navitem:uibarbuttonitem){     var addit = true     item in self.navigationitem.rightbarbuttonitems!{         if item.tag == navitem.tag{             addit = false         }     }      if addit{         self.navigationitem.rightbarbuttonitems?.append(navitem)         self.navigationitem.rightbarbuttonitems!.sortinplace({ $0.tag > $1.tag })     } } 

edit3: i've overridden sendevent method track whether or not user touching app or not, if take out code, still crashes, , debugger breaks on uiapplicationmain.

override func sendevent(event: uievent) {             super.sendevent(event)      if event.type == uieventtype.touches{         if let touches = event.alltouches(){             item in touches{                 if let touch = item as? uitouch{                     if touch.phase == uitouchphase.began{                         touchcounter++                     }else if touch.phase == uitouchphase.ended || touch.phase == uitouchphase.cancelled{                         touchcounter--                     }                      if touchcounter == 0{                         receiver?.nottouching()                     }                 }             }         }     } } 

tough one, bit more insight in events upto bug might helpful.

  1. does happen on every device (if not, devices gives troubles)
  2. it happens after "vigorously selecting" items. did device change orientation before that. happen before once rotate?
  3. what do in code when "select item".

other that, i'd start flow of removing child viewcontrollers in breakupformerviewtree() right. based on apple docs want tell child it's being removed, before removing view , removing child parent viewcontroller

https://developer.apple.com/library/ios/featuredarticles/viewcontrollerpgforiphoneos/creatingcustomcontainerviewcontrollers/creatingcustomcontainerviewcontrollers.html

here says want call willmovetoparentviewcontroller(nil) before doing removing. doesn't happens if don't, can imagine os doing lifecycle management there, preventing sending corrupt events @ later point.

https://developer.apple.com/library/ios/documentation/uikit/reference/uiviewcontroller_class/index.html#//apple_ref/occ/instm/uiviewcontroller/willmovetoparentviewcontroller:

edit (after code posted)

i don't see else in code might cause crash. memory-error stated, no idea it's coming from. try turning on zombie objects , guard malloc (scheme > run > diagnostics) , maybe can bit more info on what's causing it.

other that, i'd comment out loads of implementation, swap subclasses empty viewcontrollers until doesn't happen again. should able pinpoint part of implementation involved in creating event. once that, well, pinpoint more , evaluate every single line of code in implementation.


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -