您的位置:首页 > 产品设计 > UI/UE

使用UIImagePickerController时3DTouch引起的Crash问题的解决

2015-12-18 17:39 495 查看

开发时遇到的问题及解决方式——-

一、crash的场景

程序中用到UIImagePickerController时,如果在IPhone6S上运行APP,当forceTouch 一个图片时程序会crash,并附带如下crash message:

* Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘+[NSObject previewingContext:viewControllerForLocation:]: unrecognized selector sent to class 0x19f678020’

这种Crash的原因很可能是苹果自身SDK的一个bug,这点我们在苹果官网上可以了解一些。https://forums.developer.apple.com/thread/21932 因为只要是利用了个UIImagePickerController这个控制器,当我们forceTouch那个选择图片的view的时候,就会crash。

二、问题的解决

我们可以从 http://download.csdn.net/detail/smiling8866/9367050 下载一下这个工具类,然后在- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions方法中调用MSDPreventImagePickerCrashOn3DTouch();方法,就可以解决以上Crash.

三、注意事项

在程序中引入以上工具类时,肯能会出现编译不过去报arm64错误,很可能是工具文件的后缀名不对。因为工具类中的代码大都是c++的,所以应该把后缀名改成 .mm;

在编译的时候,一定要把程序中所有的断点都去掉,不然代码总会卡在try catch那段异常处理的代码中。

注意,3DTouch功能,只有在Iphone6S及其以后的版本支持,XCode要用7.0及其以后的版本,所以利用低版本的XCode是编译不过的,也没有任何意义。

发布后苹果返回的log及解决方式

一、产生场景:

如果我们的App底层传输的库是利用XCode6.x的版本编译的,此时IOS的版本才是8.x,我们无法在开发的时候利用上述方式解决问题,那么我们只能保留着以上问题去把APP发布出去。。如果我们足够幸运的遇到非常调皮的用户就在照片选择器中使用了3DTouch,那么我们应用必然会Crash,苹果就会返回给我么以下的crash log:



我当时看到这种反馈日志的时候一脸的疑惑,因为我记得我并没有使用UICollectionViewController这个控制器呀,我google了一下才了解到原来是使用UIImagePickerController这个控制器,并且在使用3DTouch的时候才会出现这种情况。闭目想一下:恩,非常合理,照片选择器确实非常像UICollectionViewController。

我google到的资料地址是:http://stackoverflow.com/questions/33773712/iphone-6s-ios-9-1-crashing-on-uicollectionviewcontroller-previewingcontextvi

二、问题的解决

当然,资料的内容都是英文。下面我具体说一下他们介绍的解决方式。

我们先说OC的版本:

你需要创建一个UICollectionViewController的Category,并命名为FixCrash(当然,此名称任意)。然后必须实现UIViewControllerPreviewingDelegate这个代理。下面是具体的代码:

Header:

@interface UICollectionViewController (FixCrash) <UIViewControllerPreviewingDelegate>
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location;
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext
commitViewController:(UIViewController *)viewControllerToCommit;
@end


Implementation:

@implementation UICollectionViewController (FixCrash)
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
return nil;
}
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext
commitViewController:(UIViewController *)viewControllerToCommit {
return;
}
@end


下面是swift版本:

直接上代码,因为鄙人目前还没有时间去研究swift..只上代码不解释……

extension UICollectionViewController: UIViewControllerPreviewingDelegate {
public func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
return nil;
}

public func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {

}
}


三、注意事项

小伙伴本别忘了上面的那个必须实现的代理-UIViewControllerPreviewingDelegate,它是在IOS9.0才出来的,看看截图:



所以嘛,如果你不是利用XCode7.x进行的项目开发,那么此bug只有保留了,暂时还没有找到其它的解决方法。。我们利用XCode7.0以下的版本,运行在ios9.x上的系统中,有些bug时苹果都没有修复的,这点我在上面已经提及。。。gameover^^
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: