MPNowPlayingInfoCenter 抛出 EXC_BAD_ACCESS
MPNowPlayingInfoCenter throwing EXC_BAD_ACCESS
我正在制作一个播放音频的应用程序,我已经设置它以便通过 MPNowPlayingInfoCenter
更新锁定屏幕,但我 运行 遇到了问题。
在看似随机的时间,我在尝试更新正在播放的信息时收到 EXC_BAD_ACCESS
错误。
这是这样做的代码:
- (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% 的情况下,这是有效的,但有时当将应用程序退出后台或更改音频文件时,或者只是随机地,
[npInfoCenter setNowPlayingInfo:_activeMetadata];
抛出 EXC_BAD_ACCESS
.
此外,_activeMetadata
声明为:
@property (atomic, strong, retain) NSMutableDictionary* activeMetadata;
创建AVPlayer时实例化:
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 调用。
知道是什么导致了异常吗?
我觉得你打电话给 setNowPlayingInfo
太频繁了。当然,它确实不应该崩溃,但没有必要使用 CADisplayLink
每秒调用它 60 次。
那你为什么这么频繁地调用它?如果是为了让进度条顺畅跟踪,还是没必要。来自 MPNowPlayingInfoPropertyElapsedPlaybackTime
声明:
// 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.)
p.s。我用 m4a 文件尝试了代码,发现 durInterval
是 NotANumber。在正确的持续时间和仅调用 setNowPlayingInfo
一次的情况下,进度条跟踪良好并且没有崩溃。
Apple 在 iOS 10.3 及更高版本中修复了此崩溃。
因此,如果您想支持 iOS 10.2.1 及更低版本,请务必限制设置 [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo
属性 的频率。也许限制设置 属性 每秒一次。
我正在制作一个播放音频的应用程序,我已经设置它以便通过 MPNowPlayingInfoCenter
更新锁定屏幕,但我 运行 遇到了问题。
在看似随机的时间,我在尝试更新正在播放的信息时收到 EXC_BAD_ACCESS
错误。
这是这样做的代码:
- (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% 的情况下,这是有效的,但有时当将应用程序退出后台或更改音频文件时,或者只是随机地,
[npInfoCenter setNowPlayingInfo:_activeMetadata];
抛出 EXC_BAD_ACCESS
.
此外,_activeMetadata
声明为:
@property (atomic, strong, retain) NSMutableDictionary* activeMetadata;
创建AVPlayer时实例化:
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 调用。
知道是什么导致了异常吗?
我觉得你打电话给 setNowPlayingInfo
太频繁了。当然,它确实不应该崩溃,但没有必要使用 CADisplayLink
每秒调用它 60 次。
那你为什么这么频繁地调用它?如果是为了让进度条顺畅跟踪,还是没必要。来自 MPNowPlayingInfoPropertyElapsedPlaybackTime
声明:
// 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.)
p.s。我用 m4a 文件尝试了代码,发现 durInterval
是 NotANumber。在正确的持续时间和仅调用 setNowPlayingInfo
一次的情况下,进度条跟踪良好并且没有崩溃。
Apple 在 iOS 10.3 及更高版本中修复了此崩溃。
因此,如果您想支持 iOS 10.2.1 及更低版本,请务必限制设置 [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo
属性 的频率。也许限制设置 属性 每秒一次。