当我在选择几个项目后旋转应用程序两次时,它会崩溃.我重写了sendEvent方法,这是调试器停止的地方.当我尝试打印事件类型时,它会向我显示一些奇怪的东西(我认为这是一个不存在的内存位置):
(lldb) print event.type
(UIEventType) $R10 = <invalid> (0xff)

不知何故,我认为这与我如何处理轮换有关.我有一个主 – 细节风格的应用程序,它使用不同类型的导航来拍摄风景,拍摄肖像和手机.我创建了一个名为NavigationFlowController的类,它处理所有导航事件并相应地设置视图.在旋转时,它会分解视图树并使用正确的导航重新组合它们

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 up 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 is 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 with 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?]){
    for 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,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()
    }
}

编辑(回应贾斯汀的问题):

1)我在所有iOS8 iPad模拟器上都经历过崩溃.

2)从一个新的开始,如果我选择6-7项,然后我旋转两次,它会崩溃.但我也可以选择一个项目,旋转几次,再选择一些并继续旋转,在某些时候它会崩溃.

3)选择项目时,执行以下代码:

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)
                }
            }
        })
    }
}

然后在详细视图控制器中:

func initLayout(){
    if viewForCard == nil{
        // views not yet initialized,happens when initLayout if called from the document setter before this view has been loaded
        // just return,the layouting will be done on viewDidLoad with the correct document instead
        return
    }

    self.navigationItem.rightBarButtonItems = []

    if document == nil{
        // Removed code that 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 is there,load it
                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 the 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
    for 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 })
    }
}

编辑方式3:我已经重写了sendEvent方法来跟踪用户是否正在触摸应用程序,但即使我拿出这段代码,它仍然会崩溃,然后调试器在UIApplicationMain上中断.

override func sendEvent(event: UIEvent)
{        
    super.sendEvent(event)

    if event.type == UIEventType.touches{
        if let touches = event.alltouches(){
            for 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()
                    }
                }
            }
        }
    }
}

解决方法

艰难的一点,对这个bug的事件有点了解可能会有所帮助.

>它是否会在每台设备上发生(如果没有,哪些设备会给您带来麻烦)
>它发生在“大力选择”项目之后.您的设备在此之前是否更改了方向.在你旋转之前它也会发生吗?
>当您“选择项目”时,您在代码中做什么.

除此之外,我开始在breakupFormerViewTree()中删除你的子ViewControllers.基于Apple Docs,你想告诉孩子它被删除,然后删除视图然后最终从Parent ViewController中删除子项

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

这里它实际上表示你想在删除之前调用willMovetoParentViewController(nil).它没有说明如果你不这样做会发生什么,但我可以想象操作系统在那里进行一些生命周期管理,防止它在以后发送腐败事件.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/willMoveToParentViewController:

编辑(额外发布代码后)

我的代码中没有看到任何可能导致崩溃的内容.它确实看起来像你所说的内存错误,但不知道它来自何处.尝试打开Zombie对象和Guard Malloc(Scheme> Run> Diagnostics),也许你可以获得更多信息,了解导致它的原因.

除此之外,我只是注释掉你的实现的负载,用空的ViewControllers交换Subclasses,直到它不再发生.您应该能够确定创建此事件涉及实现的哪个部分.一旦你这样做,那就更好地指出并评估该实现中的每一行代码.

ios – 在sendEvent方法上崩溃的更多相关文章

  1. ios – 在sendEvent方法上崩溃

    当我在选择几个项目后旋转应用程序两次时,它会崩溃.我重写了sendEvent方法,这是调试器停止的地方.当我尝试打印事件类型时,它会向我显示一些奇怪的东西(我认为这是一个不存在的内存位置):不知何故,我认为这与我如何处理轮换有关.我有一个主–细节风格的应用程序,它使用不同类型的导航来拍摄风景,拍摄肖像和手机.我创建了一个名为NavigationFlowController的类,它处理所有导航事件并

  2. ios – UIDeviceOrientation ipad

    我有以下代码根据方向填充视图.这总是会返回景观.我正确地改变了视图–(void)animateRotation:(UIInterfaceOrientation)interfaceOrientation持续时间:(NSTimeInterval)持续时间{但是在更改播放列表时已经在横向或纵向中不起作用.解决方法而不是使用[[UIDevicecurrentDevice]orientation]来检查方向

  3. iOS 9中的强制视图控制器方向

    我正在制作一个摄影应用程序,允许以肖像或风景拍摄照片.由于项目的要求,我不能让设备方向自动旋转,但确实需要支持旋转.使用以下定位方法时:我可以在启动时正确设置旋转.通过更改方向值并调用UIViewController.attemptRotationToDeviceOrientation(),我能够支持旋转到新的所需接口.但是,此旋转仅在用户实际移动其设备时发生.我需要它自动发生.我可以调用:UID

  4. 小胖说swift11-------- ios 进入某个VC强转为横屏,出VC后复原

    今天做项目,某一个VC需要展现VR展览内容,产品要求这个VC可以横屏查看,因为横屏查看的时候,看的范围比较大,但是其余的VC都是竖屏显示的,为了达到某个VC横屏显示其余VC不变的效果,然后查询资料,撸代码。。

  5. 只有在Swift中,如何将一个视图控制器的方向锁定到纵向模式

    由于我的应用程序支持所有方向.我想只将肖像模式锁定到特定的UIViewController.(e.g.AssumeitwasTabbedApplicationandwhenSignInViewappearmodally,IonlywantthatSignInViewtotheportraitmodeonlynomatterhowtheuserrotatethedeviceorhowthecurre

  6. 错误:screenSize | smallestScreenSize android studio Target SDK 23

    我正在尝试将heyZap广告集成到我的应用中,但我在构建时遇到此错误:错误:screenSize|smallestScreenSize).我搜索了它,我发现它的目标sdk错误应该至少为13但是在这里我使用的是SDK23.这是我的清单文件:这是我的build.gradle文件:这是错误的图片:这是我一直关注的链接:https://developers.heyzap.com/docs/android_

  7. Android ImageView按重量调整大小,不以父LinearLayout为中心

    理想情况下,我可以设置“重力”,或者设置宽度而不需要水平LinearLayout容器和重量的一些替代方法,因为没有那个容器我可以居中在我的顶级垂直LinearLayout中水平放置.谢谢!

  8. android – 保存数据并更改方向

    我有两个活动,我使用android:configChanges=“keyboardHidden|orientation|screenSize”一个主动用于纵向到第二个横向但是当方向发生变化时,会加载活动并丢失数据如何保存数据并更改活动方向?

  9. 在指定横向时,如何防止Android Activity暂时进入纵向模式?

    我怀疑这与应用程序在从纵向屏幕启动时自动旋转的事实有关.似乎奇怪的是,应用程序已被指示永远不会以纵向方式开始,然后快速更改.但是,有没有办法让它永远不会成像?我把它放在我的Activity’sonCreate中:这导致它永远卡在那里:)解决方法将此添加到您的活动中:

  10. android – 为什么我的Button的文字会被截断?

    我有一个正常的按钮,但是文字被截断了.我不知道为什么会这样.有谁可以分析它为什么会发生?

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部