AVPlayerPeriodicCaller crash

3

I’m getting crash, and I can’t figure out what is causing it. Here what I’m getting from crash report:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000c
Triggered by Thread:  0

Thread 0 Crashed:
0   AVFoundation                    0x2f271946 -[AVPlayerPeriodicCaller _effectiveRateChanged] + 418
1   AVFoundation                    0x2f270fc8 __43-[AVPlayerTimelyCaller _timebaseDidChange:]_block_invoke + 232
2   libdispatch.dylib               0x3b04ed50 _dispatch_call_block_and_release + 8
3   libdispatch.dylib               0x3b04ed3c _dispatch_client_callout + 20
4   libdispatch.dylib               0x3b0516be _dispatch_main_queue_callback_4CF + 274
5   CoreFoundation                  0x3039b674 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4
6   CoreFoundation                  0x30399f40 __CFRunLoopRun + 1304
7   CoreFoundation                  0x303047a4 CFRunLoopRunSpecific + 520
8   CoreFoundation                  0x30304586 CFRunLoopRunInMode + 102
9   GraphicsServices                0x352716ce GSEventRunModal + 134
10  UIKit                           0x32c6388c UIApplicationMain + 1132
11  my-app                          0x00029dd4 main (main.m:16)
12  libdyld.dylib                   0x3b063ab4 start + 0

As I understand it’s coming from addPeriodicTimeObserverForInterval:queue:usingBlock:, so I’m always checking for block and queue to be correct. What else can cause this?

Thanks in advance.

UPDATE:

Here is method that calls addPeriodicTimeObserverForInterval:queue:usingBlock:

- (void)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block
{
    [block copy];
    dispatch_async(self.operationQueue, ^{
        //This method just makes sure, that self.player not nil
        [self someMethodcompletionHandler:^{
            if (self.observer) {
                [self.player removeTimeObserver:self.observer];
                self.observer = nil;
            }
            if (block && queue) {
                self.observer = [self.player addPeriodicTimeObserverForInterval:interval
                                                                          queue:queue
                                                                     usingBlock:block];
            }
        }];
    });
}

UPDATE 2:

I figured it out. But I don’t know, why that works. So my question, why it works? Why self.operationQueue better than just queue?

self.observer = [self.player addPeriodicTimeObserverForInterval:interval
                                                          queue:self.operationQueue
                                                     usingBlock:^(CMTime time){
                                                        dispatch_async(queue, ^{
                                                                         block(time);
                                                                     });
                                                    }];
ios
avfoundation
asked on Stack Overflow Mar 30, 2014 by Alfred Zien • edited Mar 30, 2014 by Alfred Zien

1 Answer

4

Official AVPlayer documentation states:

Releasing the observer object without invoking removeTimeObserver: will result in undefined behavior

This means that you should keep the value returned from addPeriodicTimeObserverForInterval:queue:usingBlock: and before the observer block is released make sure that you call removeTimeObserver:

Also note that block objects are allocated on the stack by default (not the heap) so to be sure that your block is not released when the frame ends you should retain the block by calling copy. To read more about block memory management see here.

answered on Stack Overflow Mar 30, 2014 by Tom Susel

User contributions licensed under CC BY-SA 3.0