首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MPNowPlayingInfoCenter投掷EXC_BAD_ACCESS

MPNowPlayingInfoCenter投掷EXC_BAD_ACCESS
EN

Stack Overflow用户
提问于 2016-09-18 08:01:17
回答 2查看 1K关注 0票数 2

我正在制作一个回放音频的应用程序,我已经设置了它,以便通过MPNowPlayingInfoCenter更新锁定屏幕,但我遇到了一个问题。

在看似随机的时间,我得到一个EXC_BAD_ACCESS错误时,试图更新现在播放的信息。

下面是这样做的代码:

代码语言:javascript
复制
- (void)updatePlayback
{
    if(!active)
        return;

    NowPlayingController* npc = [AudioController nowPlayingController];
    CMTime elapsed = player.currentTime;
    Float64 elInterval = CMTimeGetSeconds(elapsed);
    [npc setElapsed:elInterval];

    CMTime duration = player.currentItem.duration;
    Float64 durInterval = CMTimeGetSeconds(duration);
    [npc setRemaining:ceilf(durInterval - elInterval)];

    [npc setPlayPauseValue:isPlaying];
    if(durInterval > 0)
    {
        [npc setProgressValue:elInterval/durInterval];
        [npc setAudioDuration:durInterval];
    }

    _activeMetadata[MPMediaItemPropertyPlaybackDuration] = @(durInterval);
    _activeMetadata[MPNowPlayingInfoPropertyPlaybackRate] = @(isPlaying);
    _activeMetadata[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(elInterval);

    MPNowPlayingInfoCenter* npInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
    if(npInfoCenter && _activeMetadata)
    {
        if([npInfoCenter respondsToSelector:@selector(setNowPlayingInfo:)])
        {

//////////THE FOLLOWING LINE TRIGGERS EXC_BAD_ACCESS SOMETIMES////////////
            [npInfoCenter setNowPlayingInfo:_activeMetadata];
        }

    }
}

99.9%的情况下,这是可行的,但有时当应用程序退出后台或更改音频文件时,或者只是随机地,

代码语言:javascript
复制
[npInfoCenter setNowPlayingInfo:_activeMetadata];

抛出EXC_BAD_ACCESS

此外,_activeMetadata声明为:

代码语言:javascript
复制
@property (atomic, strong, retain) NSMutableDictionary* activeMetadata;

在创建AVPlayer时实例化它:

代码语言:javascript
复制
    AVAsset* asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:path]];
    AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
    player = [AVPlayer playerWithPlayerItem:playerItem];

    CMTime duration = player.currentItem.duration;
    NSTimeInterval durInterval = CMTimeGetSeconds(duration);
    NSLog(@"%f", durInterval);

    MPMediaItemArtwork* albumArtwork = [[MPMediaItemArtwork alloc] initWithImage:[downloader useCachedImage:CacheKeySeriesBanners withName:nil withURL:info[@"image"]]];
    NSDictionary* nowPlayingInfo = @{MPMediaItemPropertyTitle:ptString,
                                     MPMediaItemPropertyArtist:spString,
                                     MPMediaItemPropertyArtwork:albumArtwork,
                                     MPMediaItemPropertyAlbumTitle:info[@"title"],
                                     MPMediaItemPropertyPlaybackDuration:@(durInterval),
                                     MPNowPlayingInfoPropertyPlaybackRate:@(1),
                                     MPNowPlayingInfoPropertyElapsedPlaybackTime:@(0)};
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:nowPlayingInfo];

    _activeMetadata = [nowPlayingInfo mutableCopy];

updatePlayback是通过每个帧上的CADisplayLink调用的。

有什么可以导致例外的原因吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-18 12:18:20

我想你给setNowPlayingInfo打电话太频繁了。当然,它不应该崩溃,但是没有必要使用CADisplayLink每秒调用它60次。

那你为什么经常打电话给它?如果这是因为你想要进度条顺利跟踪,仍然没有必要。来自MPNowPlayingInfoPropertyElapsedPlaybackTime声明:

代码语言:javascript
复制
// The elapsed time of the now playing item, in seconds.
// Note the elapsed time will be automatically extrapolated from the previously 
// provided elapsed time and playback rate, so updating this property frequently
// is not required (or recommended.)

附注:我用m4a文件尝试了代码,发现durInterval是NotANumber。使用正确的持续时间并且只调用setNowPlayingInfo一次,进度条跟踪良好&没有崩溃。

票数 3
EN

Stack Overflow用户

发布于 2019-02-09 07:52:40

苹果公司在iOS 10.3及以上版本中修复了这一故障。因此,如果您希望支持iOS 10.2.1及更低版本,请务必控制设置[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo属性的频率。可能限制每秒钟只设置一次属性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39555416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档