如何找出什么导致在IOS 8 didHideZoomSlider错误?

以下错误不断出现在我的应用程序的crashlytics日志中

在IOS 8上:

libobjc.A.dylib objc_msgSend + 5 didHideZoomSlider: Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000e 

我不知道从哪里开始? 任何人有什么想法我应该寻找?

整个堆栈跟踪:

  0 libobjc.A.dylib objc_msgSend + 5 didHideZoomSlider: 1 Foundation __NSFireDelayedPerform + 468 2 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14 3 CoreFoundation __CFRunLoopDoTimer + 650 4 CoreFoundation __CFRunLoopRun + 1418 5 CoreFoundation CFRunLoopRunSpecific + 456 6 CoreFoundation CFRunLoopRunInMode + 106 7 GraphicsServices GSEventRunModal + 136 8 UIKit UIApplicationMain + 1440 9 main.m line 8 main 

错误消息是否意味着ImagePickerCameraView有问题?

我也有时得到

  Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0xeec1ff5e 0 libobjc.A.dylib objc_msgSend + 21 didHideZoomSlider: 

如果ImagePicker是麻烦制造者这里是代码摘录:

 - (IBAction)onTakePictureToolbarButtonPushed:(id)sender { UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; [imagePicker setSourceType: [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypePhotoLibrary ]; [imagePicker setDelegate:self]; [self presentViewController:imagePicker animated:YES completion:nil]; } - (void)imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info { UIImage* rawImage = [info objectForKey: UIImagePickerControllerOriginalImage]; NSData *imageData = UIImageJPEGRepresentation(rawImage, 0.3); [imageData writeToFile: @"img.jpg" atomically: YES]; [self dismissViewControllerAnimated: YES completion:nil]; [self.tableView reloadData]; } 

我已经能够在我的代码中复制这个问题。 这似乎是苹果代码中的一个错误,是一个计时问题。

我没有通过点击实际拍照复制它,但是当我点击取消时,我可以复制它。 你可以尝试在你的代码中做这个,看看它是否适合你。 打开相机拍照,然后捏缩放。 屏幕上会显示一个缩放滑块。 约4-5秒后,变焦幻灯片消失。 这是计时的时间点。如果你点击取消就像它开始褪色,你可以让它崩溃。

我的假设是,苹果有一个animation块,在其中淡化缩放滑块。 在完成该animation时,它会调用didHideZoomSlider:而不检查它是否参考图像select器。

我认为在我的取消代码上进行复制比较容易,因为它非常简单:

 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [self dismissViewControllerAnimated:YES completion:nil]; } 

我的假设是,由于执行速度如此之快,它可以在animation中间消除它。 因此,我的解决scheme实际上是拖延我的观点的一小段时间的解雇。

 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { __weak typeof(self) wSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [wSelf dismissViewControllerAnimated:YES completion:nil]; }); } 

我不认为这“解决”了这个问题,而是把它减less了,这样我就无法复制它了。 这应该作为一个苹果的错误(我将接下来做)。

更新:发送到苹果。

join延迟我没有太多的运气。 我的情况(iOS 8和9.0.1)仍然发生崩溃。

有一个OpenRadar ,build议删除CAMZoomSlider的代表可能是负责的崩溃,这对我很好。

用户要小心,虽然,因为这操纵一个私人类,可能会导致一个应用程序商店拒绝提交…

为了解决委托的问题, UIImagePickerController子类,并添加以下内容:

 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self clearZoomSliderDelegateForClass:[self sliderClass] subviews:self.view.subviews]; } - (void)clearZoomSliderDelegateForClass:(Class)sliderClass subviews:(NSArray *)subviews { for (UIView *subview in subviews) { if ([subview isKindOfClass:sliderClass] && [subview respondsToSelector:@selector(setDelegate:)]) { [subview performSelector:@selector(setDelegate:) withObject:nil]; return; } else { [self clearZoomSliderDelegateForClass:sliderClass subviews:subview.subviews]; } } } - (Class)sliderClass { for (NSString* prefix in @[@"CAM", @"CMK"]) { Class zoomClass = NSClassFromString([prefix stringByAppendingString:@"ZoomSlider"]); if (zoomClass != Nil) { return zoomClass; } } return Nil; } 

在iOS 9 SDK专用CameraKit框架前缀从CAM更改为CMK (只需使用可视debugging器检查滑块),因此以前的解决方法必须更新。

日志中的崩溃也可能是这样的:

 0 libobjc.A.dylib 0x3591fae6 objc_msgSend + 6 1 Foundation 0x24d28e59 __NSFireDelayedPerform + 466 ... 

这已经得到了回答,但是另一个可能的解决scheme是将video控制器中的图像采集控制器实例保留在视图控制器中,以避免在苹果的callback触发之前将其解除分配。