简体   繁体   English

如果未在块内检测到nil?

[英]If not detecting nil inside block?

I have an AVPLayer with this observer 我有这个观察者的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
          }

  }];

The player is on self.player . 播放器位于self.player

This app loads movies in sequence. 此应用按顺序加载电影。 When a movie ends, the app created a brand new AVPlayer , loads the asset and stores it on self.player . 电影结束后,该应用会创建一个全新的AVPlayer ,加载资产并将其存储在self.player Something like: 就像是:

AVPlayer *newPlayer = ... init new player
// load assets, create new periodic observers, etc.
// new player is ready
self.player = newPlayer;

This works fine but after 3 or 4 movies played, it crashes on the line 这可以正常工作,但播放3或4部电影后,它会在线崩溃

 myself.runAfterEveryFrame(currentTime);  // crashes here

with myself = nil . myself = nil

This is the question. 这是问题。 There is this if 如果有这个

          if (myself.runAfterEveryFrame) {
            Float64 currentTime = CMTimeGetSeconds([myPlayer currentTime]);
            myself.runAfterEveryFrame(currentTime);  // crashes here
          }

runAfterEveryFrame is a block of code that runs after every frame. runAfterEveryFrame是在每一帧之后运行的代码块。 if myself is nil , how is this two lines being executed? 如果myselfnil ,这两行如何执行? How can that be? 怎么可能?

if myself is nil then myself.runAfterEveryFrame is nil , and the content inside the if should not run, but it is running and crashing inside the if . 如果我本人为nil,则myself.runAfterEveryFramenil ,并且if的内容不应运行,但是它正在运行并且在if崩溃。

Assuming myself is a weak reference like myPlayer (you didn't say in your question) it can be deallocated at any time, including inside your if block. 假设myself是像myPlayer这样的弱引用(您未在问题中说过),则可以随时将其释放,包括在if块内部。 To resolve, create a strong reference inside your block: 要解决此问题,请在您的代码块内创建一个强引用:

__strong typeof(myself) strongSelf = myself;
__strong typeof(myPlayer) strongPlayer = myPlayer;

if (strongSelf.runAfterEveryFrame) {
    Float64 currentTime = CMTimeGetSeconds([strongPlayer currentTime]);
    strongSelf.runAfterEveryFrame(currentTime);
}

Also, you should be checking whether CMTimeGetSeconds returns NaN or infinity to be safe. 另外,您应该检查CMTimeGetSeconds是否返回NaN或Infinity以确保安全。

a 2nd use of a weak variable inside an asynchronous block isn't safe so always cast the weak to a strong var inside the block. 第二次在异步块中使用弱变量是不安全的,因此始终将弱变量强制转换为块内的强变量。 so self is captured weak but retained from the block 所以自我被软弱地俘获了,但是被挡住了

    __weak myType *weakType = self;

    //dispatch block

   //INSIDE block
    __strong myType *strongType = weakType;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM