Как узнать, что вызывает ошибку didHideZoomSlider в IOS 8?
Следующая ошибка продолжает появляться в моих журналах аварийных сообщений приложения
в 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
Значит ли ошибка msg, что что-то не так с 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];
}
Ответы
Ответ 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.
Ответ 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;
}
В префиксе рамки IK9 SDK private CameraKit изменен с CAM
на CMK
(просто проверьте слайдер с визуальным отладчиком), поэтому предыдущее обходное решение должно быть обновлено.
Эта ошибка также может выглядеть в журналах:
0 libobjc.A.dylib 0x3591fae6 objc_msgSend + 6
1 Foundation 0x24d28e59 __NSFireDelayedPerform + 466
...
Ответ 3
Это уже ответили, но другое потенциальное решение здесь состояло в том, чтобы сохранить экземпляр контроллера выбора изображения внутри контроллера представления, чтобы избежать его освобождения до запуска обратного вызова яблока.