Warning about saving the loop in the __block variable, which is ivar

I will subclass AVQueuePlayer, and in my constructor, where I pass AVPlayerItem, he needs to play, I want to add an observer to the first element for playback.

So, I am using the AVPlayer method addBoundaryTimeObserverForTimes:queue:usingBlock:. For the correct implementation, I need to call removeTimeObserver:on the "opaque" object returned by the addBoundary method.

To save the object, no matter how long it was needed, I declared it as __block ivar:

@property (nonatomic, copy) __block id obs;

then in my own initialization method I:

__block AVPlayer* blockPlayer = self;

_obs = [self addBoundaryTimeObserverForTimes: times
             queue:NULL
             usingBlock:^{ 

                 // Post a notification that I can then act on
             [[NSNotificationCenter defaultCenter]
                      postNotificationName:@"PlaybackStartedNotification"
                      object:nil];

                  // Remove the boundary time observer
             [blockPlayer removeTimeObserver:_obs]; // Warning here
                          }];     

... , , , , : part. ...

() -.

, ?

: @property __block id observer, , __block id obs. ! (Awesome!)

+4
1

( , , !)

, , __block - , , . :

, , __block ivar:

@property (nonatomic, copy) __block id observer;

- , - , - - . Apple, , __block, - , SO- ( Apple, ).

:

__block AVPlayer* blockPlayer = self;

blockPlayer self, . , , () ... , :

__weak AVPlayer *blockPlayer = self;

, , NULL - , , , . :

// Remove the boundary time observer if blockPlayer still exists
AVPlayer *strongBlockPlayer = blockPlayer; // obtain strong reference from weak one
if (strongBlockPlayer)
    [strongBlockPlayer ...];

. :

_obs = [self addBoundaryTimeObserverForTimes:times
                                       queue:NULL
                                  usingBlock:^{ 
          ...
          [blockPlayer removeTimeObserver:_obs];
        }];

_obs .

, _obs observer? :

_obs , . , , , , _obs. _obs , addBoundaryTimeObserverForTimes:queue:usingBlock: , , ..

. ​​ __block, , , , , - , / .

, , :

__block id obs = [self addBoundaryTimeObserverForTimes:times
                                                 queue:NULL
                                            usingBlock:^{ 
                    ...
                    [blockPlayer removeTimeObserver:obs];
                  }];

:

  • obs , , ( , - , );
  • jobs;
  • addBoundaryTimeObserverForTimes:queue:usingBlock: ;
  • obs;
  • ( ) , obs , .

, _obs observer, LHS self.observer, RHS blockPlayer.observer, :

__weak AVPlayer *blockPlayer = self;
self.observer = [self addBoundaryTimeObserverForTimes:times
                                                queue:NULL
                                           usingBlock:^{ 
                   ...
                   // Remove the boundary time observer if blockPlayer still exists
                   AVPlayer *strongBlockPlayer = blockPlayer; // obtain strong reference from weak one
                   if (strongBlockPlayer)
                      [strongBlockPlayer removeTimeObserver:strongBlockPlayer.observer];
                 }];

, strongBlockPlayer.observer, addBoundaryTimeObserverForTimes:queue:usingBlock: .

obs/observer?

, , ? , , (a) - , (b) , , , , , , , - !

+2

All Articles