Подтвердить что ты не робот

Как узнать, что вызывает ошибку 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];

}
4b9b3361

Ответ 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

Это уже ответили, но другое потенциальное решение здесь состояло в том, чтобы сохранить экземпляр контроллера выбора изображения внутри контроллера представления, чтобы избежать его освобождения до запуска обратного вызова яблока.