1

我和这个观察者有一个 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是在每一帧之后运行的代码块。如果myselfnil,这两行是如何执行的?这个怎么可能?

如果我自己是 nil 那么myself.runAfterEveryFramenil,并且里面的内容if不应该运行,但是它在里面运行和崩溃if

4

2 回答 2

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 或无穷大是安全的。

于 2014-12-26T17:33:47.790 回答
-1

在异步块内第二次使用弱变量是不安全的,因此始终将弱变量转换为块内的强变量。所以 self 被弱捕获但从块中保留

    __weak myType *weakType = self;

    //dispatch block

   //INSIDE block
    __strong myType *strongType = weakType;
于 2014-12-26T17:30:02.667 回答