[英]If not detecting nil inside block?
我有这个观察者的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
,加载资产并将其存储在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
,这两行如何执行? 怎么可能?
如果我本人为nil,则myself.runAfterEveryFrame
为nil
,并且if
的内容不应运行,但是它正在运行并且在if
崩溃。
假设myself
是像myPlayer
这样的弱引用(您未在问题中说过),则可以随时将其释放,包括在if
块内部。 要解决此问题,请在您的代码块内创建一个强引用:
__strong typeof(myself) strongSelf = myself;
__strong typeof(myPlayer) strongPlayer = myPlayer;
if (strongSelf.runAfterEveryFrame) {
Float64 currentTime = CMTimeGetSeconds([strongPlayer currentTime]);
strongSelf.runAfterEveryFrame(currentTime);
}
另外,您应该检查CMTimeGetSeconds
是否返回NaN或Infinity以确保安全。
第二次在异步块中使用弱变量是不安全的,因此始终将弱变量强制转换为块内的强变量。 所以自我被软弱地俘获了,但是被挡住了
__weak myType *weakType = self;
//dispatch block
//INSIDE block
__strong myType *strongType = weakType;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.