сбой для @escaping @callee_guaranteed (@unowned CMTime),добавьте код(guard let self = self else{return}) в блок,но он не работает

#ios #swift #crash #avplayer

#iOS #быстрый #авария #avplayer

Вопрос:

Мои пользователи столкнулись с этим сбоем, о котором сообщалось в Firebase Crashlytics. Я вижу класс и метод, в которых произошел сбой, но не смог выяснить причину сбоя. Все отлично работает внутри симулятора и на реальном устройстве, которое у меня есть.

 guard let self = self else{return}  

добавьте этот код, но он не работает.Мне нужна помощь в выяснении фактической причины этой аварии. Вот журнал сбоев.

 Crashed: com.apple.main-thread 0 FPMeditation 0x16c234 closure #1 in PlayerManager.addPlayObserver()   4376789556 (AudioPlayer.swift:4376789556) 1 FPMeditation 0x166f74 thunk for @escaping @callee_guaranteed (@unowned CMTime) -gt; ()   4376768372 (lt;compiler-generatedgt;:4376768372) 2 AVFCore 0xc46c -[AVPeriodicTimebaseObserver _fireBlockForTime:]   68 3 AVFCore 0xc3ac -[AVPeriodicTimebaseObserver _handleTimeDiscontinuity]   168 4 AVFCore 0xbf2c __AVTimebaseObserver_timebaseNotificationCallback_block_invoke   116 5 libdispatch.dylib 0x2914 _dispatch_call_block_and_release   32 6 libdispatch.dylib 0x4660 _dispatch_client_callout   20 7 libdispatch.dylib 0x12b60 _dispatch_main_queue_callback_4CF   944 8 CoreFoundation 0x51cd4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__   16 9 CoreFoundation 0xbeac __CFRunLoopRun   2540 10 CoreFoundation 0x1f3b8 CFRunLoopRunSpecific   600 11 GraphicsServices 0x138c GSEventRunModal   164 12 UIKitCore 0x5196a8 -[UIApplication _run]   1100 13 UIKitCore 0x2987f4 UIApplicationMain   2092 14 libswiftUIKit.dylib 0x31184 UIApplicationMain(_:_:_:_:)   104 15 FPMeditation 0x3491c main   4375513372 (ReminderTableViewCell.swift:4375513372) 16 ??? 0x103281a24 (缺少)  

И фактический код.

 private func addPlayObserver() { //播放状态监听  avPlayer.currentItem?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)  //缓冲状态监听  avPlayer.currentItem?.addObserver(self, forKeyPath: "loadedTimeRanges", options: NSKeyValueObservingOptions.new, context: nil)   avPlayer.addObserver(self, forKeyPath: "loadedTimeRanges", options: NSKeyValueObservingOptions.new, context: nil)  AVAudioSession.sharedInstance().addObserver(self, forKeyPath: "isOtherAudioPlaying", options: NSKeyValueObservingOptions.new, context: nil)    //播放结束事件监听  NotificationCenter.default.addObserver(self, selector: #selector(onItemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.avPlayer.currentItem)  //播放失败监听  NotificationCenter.default.addObserver(self, selector: #selector(onItemFailedToPlayToEndTime), name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime, object: self.avPlayer.currentItem)    NotificationCenter.default.addObserver(self, selector: #selector(onItemPlaybackStalled), name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: self.avPlayer.currentItem)  //监听普通被打断事件比如电话和闹钟  NotificationCenter.default.addObserver(self, selector: #selector(interruptionNotification), name: AVAudioSession.interruptionNotification, object: nil)    //是否开始播放  var isStartPlay = false  //设置定时监听,更新播放进度  timeObserver = avPlayer.addPeriodicTimeObserver(forInterval: CMTime.init(value: 1, timescale: 1), queue: DispatchQueue.main, using: {[weak self] (time) in  guard let self = self else{return}  //加载完成开始播放  //添加前置判断条件“self?.playStatus != .prepare”的原因:  //有时候,可能先播放了,ready事件稍后才回来.比如:  //1. play的同时,调用了seekto  //2. 本地音乐也是  if isStartPlay == false, time.value gt; 0, self.playStatus != .prepare {  isStartPlay = true  self.playStatus = .play  }    //开始播放才  if time.value gt; 0{  //计算播放进度  self.playProgress = self.calculatePlayProgress()  }    //播放进度  if (self.playStatus == .play) {//状态过滤,避免ready事件还没回来,duration为0  let progress = time.seconds / CMTimeGetSeconds((self.avPlayer.currentItem!.duration))  self.currentProgress = progress  //进度到20%时是否打统计  if progress == 0.2 amp;amp; self.isStatisticWhenTwenteen == true {  self.isStatisticWhenTwenteen = false  self.handleStatisticPlayProgress()  }  //设置实际播放时间  PlayerFinishManager.shared.setupRealPlayRealTotalTime(seconds: Int(self.avPlayer.currentItem!.duration.seconds))  }  }) }  

Комментарии:

1. Я вижу несколько self.avPlayer.currentItem! , а что, если currentItem ноль? Он будет обналичен здесь… Кроме того, у вас есть какой-нибудь метод addPlayObserver ? Это тот самый?

2. Здравствуйте,спасибо за ваш ответ,код метода завершен.

3. Может быть, эта строка let progress = time.seconds / CMTimeGetSeconds((self.avPlayer.currentItem!.duration)) заканчивается делением на 0.

4. это возможно,позвольте мне изменить это и попробовать. Спасибо.