我有一个这个观察者的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
,这两行是如何执行的?怎么会这样?
如果我自己为零,那么myself.runAfterEveryFrame
为nil
,if
内的内容不应该运行,但它正在if
内运行并崩溃。
答案 0 :(得分:2)
假设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或无穷大是安全的。
答案 1 :(得分:-1)
在异步块内第二次使用弱变量是不安全的,所以总是将弱转换为块内的强变量。所以自我被捕获弱,但保留在块
__weak myType *weakType = self;
//dispatch block
//INSIDE block
__strong myType *strongType = weakType;