我和这个观察者有一个 AVPLayer
__weak typeof(self.player) myPlayer = self.player;
myself.timer = [myself.player addPeriodicTimeObserverForInterval:interval
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)
usingBlock: ^(CMTime time) {
if (myself.runAfterEveryFrame) {
Float64 currentTime = CMTimeGetSeconds([myPlayer currentTime]);
myself.runAfterEveryFrame(currentTime); // crashes here
}
}];
播放器在 self.player
上。
此应用按顺序加载电影。当电影结束时,该应用会创建一个全新的 AVPlayer
,加载 Assets 并将其存储在 self.player
上。像这样的东西:
AVPlayer *newPlayer = ... init new player
// load assets, create new periodic observers, etc.
// new player is ready
self.player = newPlayer;
这工作正常,但在播放 3 或 4 部电影后,它在线上崩溃了
myself.runAfterEveryFrame(currentTime); // crashes here
使用 myself = nil
。
这就是问题。有这个如果
if (myself.runAfterEveryFrame) {
Float64 currentTime = CMTimeGetSeconds([myPlayer currentTime]);
myself.runAfterEveryFrame(currentTime); // crashes here
}
runAfterEveryFrame
是在每一帧之后运行的代码块。如果myself
是nil
,这两行是如何执行的?怎么可能?
if myself is nil then myself.runAfterEveryFrame
is nil
, if
里面的内容不应该运行,但是它正在运行并且在 if
中崩溃。
最佳答案
假设 myself
是一个像 myPlayer
这样的弱引用(你没有在你的问题中说)它可以在任何时候被释放,包括在你的 if
block 。要解决这个问题,请在您的 block 中创建一个强引用:
__strong typeof(myself) strongSelf = myself;
__strong typeof(myPlayer) strongPlayer = myPlayer;
if (strongSelf.runAfterEveryFrame) {
Float64 currentTime = CMTimeGetSeconds([strongPlayer currentTime]);
strongSelf.runAfterEveryFrame(currentTime);
}
另外,为了安全起见,您应该检查 CMTimeGetSeconds
是否返回 NaN 或无穷大。
关于ios - 如果没有在 block 内检测到 nil ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27659946/