【问题标题】:App freezes and crashes with kernel panic -应用程序因内核恐慌而死机和崩溃 -
【发布时间】:2014-07-04 13:21:33
【问题描述】:

我有一个应用程序,它显示一些由播放 MIDI 文件触发的基本动画。它在第一次播放期间工作正常,但在后续播放期间冻结。然后设备通常会重新启动,生成一个崩溃日志,表明发生了内核恐慌。有时它只是挂起而不重新启动。

动画由一个小的 png 图像组成,它的不透明度从高到低变化以产生淡化效果。

冻结发生在线:[self performSelectorOnMainThread:@selector( setPitch: ) withObject:[NSNumber numberWithInteger:[note intValue]] waitUntilDone:YES];

这是包含这一行的方法:

- (void)log:(NSNotification *)notification {

[NSThread isMainThread];

NSDictionary* info = notification.userInfo;


NSNumber *note;
note = [info objectForKey:kNAMIDI_Note];

BRMidiNoteName *noteConverter = [[BRMidiNoteName alloc] init];

NSString *noteName;
noteName = [noteConverter nameFromNumber:[note intValue] withNotation:[defaults valueForKey:kSettingsNotation]];


[self.currentNoteLabel performSelectorOnMainThread: @selector( setText: ) withObject: noteName waitUntilDone: YES];
[self performSelectorOnMainThread:@selector( setPitch: ) withObject:[NSNumber numberWithInteger:[note intValue]] waitUntilDone:YES];

}


-(void) setPitch:(NSNumber*) pitchValue{

NSInteger visualPitchValue = [pitchValue intValue]- [_currentTrack.trackStartNote intValue] - voiceTransposeValue + 1;

if ([defaults boolForKey:kSettingsVisualiser]) {
    //UIImageView *img = [[UIImageView alloc]init];
    UIImageView *img; 

    if ((visualPitchValue > 0 )) {

        // highlight new pitch
        img = (UIImageView *)[self.view viewWithTag:visualPitchValue];

        if (([pitchValue integerValue] < [currentVoice.bridgeLow integerValue])) {
            [img setImage:[UIImage imageNamed:@"bar_green.png"]];
        }
        else if (([pitchValue integerValue] <= [currentVoice.bridgeHigh integerValue])) {
            [img setImage:[UIImage imageNamed:@"bar_orange"]];
        }
        else{
            [img setImage:[UIImage imageNamed:@"bar_blue.png"]];
        }
        [img setAlpha:1.0];


        // Set up fade out effect
        CABasicAnimation *fadeOutAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        [fadeOutAnimation setToValue:[NSNumber numberWithFloat:_fadeToOpacity]];
        fadeOutAnimation.fillMode = kCAFillModeForwards;
        fadeOutAnimation.removedOnCompletion = NO;

        CAAnimationGroup *group = [CAAnimationGroup animation];
        group.fillMode = kCAFillModeForwards;
        group.removedOnCompletion = NO;
        // [group setAnimations:[NSArray arrayWithObjects:fadeOutAnimation, pathAnimation, nil]];
        [group setAnimations:[NSArray arrayWithObjects:fadeOutAnimation, nil]];
        group.duration = 0.7f;
        group.delegate = self;
        [group setValue:img forKey:@"imageViewBeingAnimated"];

        [img.layer addAnimation:group forKey:@"savingAnimation"];

    }
}
}

【问题讨论】:

    标签: ios objective-c cocoa-touch core-animation


    【解决方案1】:

    我发现将 waitUntilDone 从 YES 更改为 NO 会阻止设备屏幕冻结。

    [self.currentNoteLabel performSelectorOnMainThread: @selector( setText: ) withObject: noteName waitUntilDone: NO];
    [self performSelectorOnMainThread:@selector( setPitch: ) withObject:[NSNumber numberWithInteger:[note intValue]] waitUntilDone:NO];
    

    【讨论】:

    • 这很明显 - waitUntilDone 阻塞了主线程,iOS 有一个时间限制,如果主线程被阻塞,它会终止应用程序。
    • 时间限制是多少? setPitch 不应该花费太长时间以至于超过时间限制 - 只是一个简短的动画,并且大部分时间都可以正常工作。
    • 另外,为什么这会导致内核崩溃并重新启动设备?如果 Watchdog 死锁主线程,为什么不直接杀死应用程序?
    猜你喜欢
    • 2013-12-12
    • 2015-12-18
    • 2014-10-10
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 2012-02-08
    • 2015-12-11
    • 2023-03-26
    相关资源
    最近更新 更多