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
.
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. 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.
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.