I have an AVPLayer with this observer
__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
.
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
. 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
myself.runAfterEveryFrame(currentTime); // crashes here
with 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. if myself
is nil
, how is this two lines being executed? 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
.
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;