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

Posted

技术标签:

【中文标题】如何找出导致 IOS 8 上的 didHideZoomSlider 错误的原因?【英文标题】:How-to find out what causes a didHideZoomSlider error on IOS 8? 【发布时间】:2014-11-10 13:00:03 【问题描述】:

我的应用程序的 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];


【问题讨论】:

你应该粘贴你的代码:) 代码库很大,我不知道是什么导致了错误? 由于 didHideZoomSlider: 是 CAMCameraView 类的一个方法(它是一个私有的),您应该分析使用相机的代码部分。 我们无法以这种方式帮助您。 复制:当您放大时,会出现一个滑块,大约 3 秒后会出现动画。我相信一旦完成,就会调用“didHideZoomSlider”。您需要缩放,然后拍照或取消以关闭视图。要让它崩溃,必须在滑块开始消失后但在结束之前关闭视图。 【参考方案1】:

我已经能够在我的代码中复制这个问题。这似乎是 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。

【讨论】:

非常感谢!我可以确认我可以重现错误(尽管我需要 10 次尝试)。关于这个问题,我可以在一个地方查找所有 IOS 错误报告并跟踪它们的状态。再次感谢你! 是的,我也花了几次。 :) 看起来您无法查看其他人的错误报告(我也不知道)。 ***.com/questions/144873/… 这个修复不会只是改变时间错误而不实际删除它吗? @RonLugge 是正确的。如前所述,它实际上并没有修复错误。请参阅下面的adamup的答案。这似乎是一个更好的“修复”。 @RyanJM 不幸的是,它只修复了取消 - 而不是实际拍摄照片时也相关的崩溃。【参考方案2】:

我没有太多运气添加延迟。在我的情况下仍然发生崩溃(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
...

【讨论】:

有人在生产应用中使用它吗? 我已经在生产环境中使用了几个月 - 到目前为止没有任何问题。在 App Store 审核期间没有被拒绝。 非常感谢 - 这帮助我避免了崩溃......顺便说一句,我还在 8.3 上。 在 iOS 9 上修复了错误?在 iOS 9 上运行此解决方法是否安全? @LiamB 很高兴它有帮助!感谢反馈:iOS9。自从我添加了修复程序以来,我还没有看到过一次崩溃。【参考方案3】:

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

【讨论】:

谢谢@shawnwall。我实际上保留了我的 UIImagePickerController,但我仍然遇到崩溃。

以上是关于如何找出导致 IOS 8 上的 didHideZoomSlider 错误的原因?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 8 上的 snapshotViewAfterScreenUpdates 故障

ios9 上的应用程序驱逐。如何检查导致这些的原因?

如何从终端访问 iOS 8 设备上的应用程序数据?

如何在iOS 8上的Cordova / PhoneGap应用程序中隐藏键盘表格附件栏? [重复]

如何在 iOS 8 上的 Cordova / PhoneGap 应用程序中隐藏键盘表单附件栏? [复制]

iOS 8自定义键盘:更改高度