如何找出IOS 8上导致didHideZoomSlider错误的原因?

时间:2014-11-10 13:00:03

标签: ios ios8 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];

}

3 个答案:

答案 0 :(得分:29)

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

我没有通过点击实际拍摄照片来复制它,但是当我点击取消时我可以复制它。您可以尝试在代码中执行此操作,并查看它是否适合您。打开相机拍照,然后捏缩放。您将在屏幕上显示一个小缩放滑块。大约4-5秒之后,变焦幻灯片逐渐消失。这就是时间进入的地方。如果你点击取消只是,因为它开始消失,你可以让它崩溃。

我的假设是Apple有一个动画块,它会缩小缩放滑块。在完成该动画时,它会调用didHideZoomSlider:而不检查它对图像选择器的引用。

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

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

我的假设是,由于执行速度太快,因此可以在动画中间将其关闭。因此,我的解决方案是在很短的时间内实际延迟我对视图的解雇。

- (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];
    });
}

我不认为这会“修复”这个问题,但会减少它,以至于我再也无法复制它了。这应该是Apple的错误(我接下来会做)。

更新:发送给Apple。

答案 1 :(得分:13)

添加延迟我没有多少运气。崩溃仍然发生在我的案例中(iOS 8和9.0.1)。

OpenRadar建议删除可能导致崩溃的CAMZoomSlider代表,这对我来说效果很好。

用户要小心,因为这会操纵私有类,并可能导致App Store提交拒绝...

修复委托,子类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(只需使用可视调试器检查滑块),因此必须更新以前的解决方法。

此崩溃在日志中也可能如下所示:

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

答案 2 :(得分:0)

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