添加ActivityIndi​​cator并在AVPlayer上删除addObserver

时间:2016-07-24 17:06:12

标签: ios objective-c swift swift2 avplayer

我试图在播放器(缓冲或加载)以及开始播放时ActivityIndicator显示ActivityIndicator停止ActivityIndicator。此外,当我停止播放器时,AVPlayer的(removeObserver或deallocObservers)。 当我播放音乐时,它会显示var selectIndex:Int = -1 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{ let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! RadioCollectionViewCell cell.backgroundColor = UIColor.yellowColor() let object = objects[indexPath.row] cell.img.image = UIImage(named: object["image"]!) cell.btnPlay.addTarget(self, action: Selector("audioControlButtonAction:"), forControlEvents: UIControlEvents.TouchUpInside) cell.btnPlay.tag = indexPath.row+1 return cell } func audioControlButtonAction(sender: UIButton){ if player != nil && player?.currentItem != nil { deallocObservers(player!) } var btn:NSInteger btn = sender.tag as NSInteger let object = objects[btn-1] let nurl = NSURL(string: "\(object["url"]!)")! playerItem = AVPlayerItem(URL: nurl) player=AVPlayer(playerItem: playerItem!) print(selectIndex) if selectIndex != -1 && selectIndex != sender.tag { let bt:UIButton = self.view.viewWithTag(selectIndex) as! UIButton if bt.selected == true { bt.selected = false deallocObservers(player!) } } if sender.selected == false { player!.addObserver(self, forKeyPath: "status", options:NSKeyValueObservingOptions(), context: nil) player!.addObserver(self, forKeyPath: "playbackBufferEmpty", options:NSKeyValueObservingOptions(), context: nil) // player!.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options:NSKeyValueObservingOptions(), context: nil) player!.addObserver(self, forKeyPath: "loadedTimeRanges", options: NSKeyValueObservingOptions(), context: nil) player!.play() sender.selected = true selectIndex = sender.tag activityView.startAnimating() // self.view.userInteractionEnabled = false } else { deallocObservers(player!) player?.pause() sender.selected = false selectIndex = -1 } print(selectIndex) } func deallocObservers(player: AVPlayer) { player.removeObserver(self, forKeyPath: "status") player.removeObserver(self, forKeyPath: "playbackBufferEmpty") // player.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp") player.removeObserver(self, forKeyPath: "loadedTimeRanges") } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>){ if object?.isEqual(player) == true && keyPath == "status" { print("status") if player?.status == AVPlayerStatus.ReadyToPlay{ print("AVPlayerStatus.ReadyToPlay") activityView.stopAnimating() // self.view.userInteractionEnabled = true }else{ print("AVPlayerStatus.NotReadyToPlay") activityView.startAnimating() // self.view.userInteractionEnabled = false } //if keyPath == "playbackLikelyToKeepUp" { //activityView.stopAnimating() ////self.view.userInteractionEnabled = true //print("playbackLikelyToKeepUp") //} if keyPath == "playbackBufferEmpty" { activityView.startAnimating() self.view.userInteractionEnabled = false let createAccountErrorAlert: UIAlertView = UIAlertView() createAccountErrorAlert.delegate = self createAccountErrorAlert.title = "No Internet Connection" createAccountErrorAlert.message = "Make sure your device is connected to the internet." createAccountErrorAlert.addButtonWithTitle("Dismiss") createAccountErrorAlert.show() print("playbackBufferEmpty") } if player?.status == AVPlayerStatus.Failed{ print("Something went wrong . player.error should contain some information") } } } ,直到它准备好播放,但它会在播放前4,5秒停止播放ActivityIndi​​cator。问题是,当我停止AVPlayer或点击另一个播放按钮时,它会在删除AVPlayer观察者时出错。 任何人都可以告诉我我的代码中的错误在哪里以及如何解决它感谢。

-1
1
status
AVPlayerStatus.ReadyToPlay
1
2016-07-24 21:51:00.585 Radio[777:23560] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <Radio.RadioCollectionViewController 0x7fbe39d47f70> for the key path "status" from <AVPlayer 0x7fbe39e67410> because it is not registered as an observer.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001019b2e65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000103b51deb objc_exception_throw + 48
    2   CoreFoundation                      0x00000001019b2d9d +[NSException raise:format:] + 205
    3   Foundation                          0x0000000101fc4d51 -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 504
    4   Foundation                          0x0000000101fc4abd -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 84
    5   Radio                               0x00000001014a935d _TFC5Radio29RadioCollectionViewController16deallocObserversfS0_FCSo8AVPlayerT_ + 141
    6   Radio                               0x00000001014a8fbe _TFC5Radio29RadioCollectionViewController24audioControlButtonActionfS0_FCSo8UIButtonT_ + 5326
    7   Radio                               0x00000001014a92ba _TToFC5Radio29RadioCollectionViewController24audioControlButtonActionfS0_FCSo8UIButtonT_ + 58
    8   UIKit                               0x0000000102630194 -[UIApplication sendAction:to:from:forEvent:] + 92
    9   UIKit                               0x000000010279f6fc -[UIControl sendAction:to:forEvent:] + 67
    10  UIKit                               0x000000010279f9c8 -[UIControl _sendActionsForEvents:withEvent:] + 311
    11  UIKit                               0x000000010279eaf8 -[UIControl touchesEnded:withEvent:] + 601
    12  UIKit                               0x000000010269f49b -[UIWindow _sendTouchesForEvent:] + 835
    13  UIKit                               0x00000001026a01d0 -[UIWindow sendEvent:] + 865
    14  UIKit                               0x000000010264eb66 -[UIApplication sendEvent:] + 263
    15  UIKit                               0x0000000102628d97 _UIApplicationHandleEventQueue + 6844
    16  CoreFoundation                      0x00000001018dea31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    17  CoreFoundation                      0x00000001018d495c __CFRunLoopDoSources0 + 556
    18  CoreFoundation                      0x00000001018d3e13 __CFRunLoopRun + 867
    19  CoreFoundation                      0x00000001018d3828 CFRunLoopRunSpecific + 488
    20  GraphicsServices                    0x0000000106247ad2 GSEventRunModal + 161
    21  UIKit                               0x000000010262e610 UIApplicationMain + 171
    22  Radio                               0x00000001014afd5d main + 109
    23  libdyld.dylib                       0x000000010468892d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
  

输出

status observer

我找到了从此链接中删除@try { [player removeObserver:self forKeyPath:@"status"]; } @catch (NSException *exception) { } @finally { } – 的解决方案,但我不知道如何在swift中转换它。

  

解决方案

Private Sub txtFilter_AfterUpdate()  

     Dim strFilter As String
     Dim strWildcard As String
     If Len(Trim(Me.txtfilter.Value & vbNullString)) > 0 Then
        strWildcard = " Like '*" & Replace(Me.txtfilter.Value, "'", "''") & "*'"
        strFilter = "orderstatus" & strWildcard  & " And ordersales"  & strWildcard 
        Me.Filter = strFilter
        Me.FilterOn = True
     Else
        Me.FilterOn = False
     End If

End Sub

3 个答案:

答案 0 :(得分:1)

问题在于&#34; deallocObservers&#34;方法被调用两次而不在这两个调用之间添加任何观察者。我想曾经在这里:

    if player != nil && player?.currentItem != nil {
        deallocObservers(player!)
    }

第二次调用此方法时,播放器变量和当前项目不会为空。第二次调用deallocObservers可能就在这里:

        if bt.selected == true
        {
            bt.selected = false
            deallocObservers(player!)
        }

我会在deallocObservers方法中放置一个断点,以查看调用此方法的次数以及调用它的方式(查看堆栈跟踪)。

答案 1 :(得分:1)

的快速版本

目标C

@try { [player removeObserver:self forKeyPath:@"status"]; } @catch (NSException *exception) { } @finally { } 

<强>夫特

Error Handling in Swift2

do {
          try player.removeObserver(self, forKeyPath: "status")
        }

  catch {
    print("error")
  }
    defer{
      print("finally statement here")
    }

答案 2 :(得分:0)

我添加了对这些条件的检查。

var check = true
func audioControlButtonAction(sender: UIButton){

        if check == false {
            deallocObservers(player!)
        }
        if sender.selected == false{
            check = false
        }
        else{
            check = true
        }        
    }
相关问题