Luda
Luda

Reputation: 7068

Where should I add and remove observer in UICollectionViewCell?

There is something I am missing in my understanding of UICollectionViewCell lifecycle.

When UICollectionViewCell is created and configured I add observer on one of its properties

func setCellDetails(someDetails:SomeObject)
{
    ...
    self.someProperty.addObserver(self, forKeyPath: "objectProperty", options: .New, context: nil)
    ...
}

I remove the observer on prepareForReuse

override func prepareForReuse()
{
    super.prepareForReuse()
    self.someProperty.removeObserver(self, forKeyPath: "objectProperty")
}

But then when I am jumping between tabs of the application and influence the objectProperty the cell is not effected. I debugged the code and found that when I am changing the tabs, prepareForReuse of the cell is called so the observer is removed and it never added back because cell setup function is not called. So maybe I should add or remove the observer in other functions?


I tried to put the removeObserver in deinit and it crashes with the following error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x12eb89dd0 of class ObservedObject was deallocated while key value observers were still registered with it. Current observation info: NSKeyValueObservationInfo NSKeyValueObservance Observer: .. Key path: objectProperty

I thought maybe not to put removeObserver in anyplace. It produced the same error.

What should I do? Where should I put it?

Upvotes: 1

Views: 1870

Answers (2)

Amr Mohamed
Amr Mohamed

Reputation: 2380

Hey Luda finally found a solution for this problem All you have to do is subclass the AVPlayerItem and use protocols to delegate back to your class and here is how I did it

protocol AMPlayerItemDelegate {
    func playbackLikelyToKeepUp()
}

class AMPlayerItem: AVPlayerItem {

   var delegate : MyPlayerItemDelegate?

   init(URL: NSURL) {
       super.init(asset: AVAsset(URL: URL) , automaticallyLoadedAssetKeys:[])
       self.addMyObservers()
   }

   deinit {
       self.removeMyObservers()
   }

   func addMyObservers() {
       print("Adding")
       self.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: [.New], context: nil)
   }

   func removeMyObservers() {
       print("Removing")
       self.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp", context: nil)
   }

   override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
       if keyPath == "playbackLikelyToKeepUp" {
           self.delegate?.playbackLikelyToKeepUp()
       }
   }

}

Also check out my Question

Upvotes: 0

Vizllx
Vizllx

Reputation: 9246

Try to remove the observer from collection view's delegate method:- collectionView:didEndDisplayingCell:forItemAtIndexPath:

Upvotes: 0

Related Questions