2017-06-27 20 views
0

我的應用程序崩潰,而留下UIViewController以下錯誤。應用程序崩潰,同時離開UIViewController

[FeedSingleViewCell挽留]:在我的UIViewController發送到釋放實例 0x7ffbb8950a00

消息,我用UITableView並有自動播放功能,當視頻結束或當用戶離開當前UIViewController,在ViewWillDisAppear我做AVPlayer零,刪除AVPlayer子層,但它仍然崩潰。

示例代碼

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.lblNoVideo.text = [NSString stringWithFormat:@"Video from %@ is may be hidden by you.", self.objOtherUser.strUserName]; 

    arrOtherVideos   = [[NSMutableArray alloc] init]; 
    arrSelectedIndexPath = [[NSMutableArray alloc] init]; 
    arrAddedPlayerIndexPath = [[NSMutableArray alloc] init]; 
    self.arrAddedVideo  = [[NSMutableArray alloc] init]; 
    self.arrPlayedVideo  = [[NSMutableArray alloc] init]; 
    self.arrAddedVideoCell = [[NSMutableArray alloc] init]; 

    self.navigationController.interactivePopGestureRecognizer.delegate = self; 
    [self.navigationController.interactivePopGestureRecognizer setEnabled:YES]; 

    [self initFooterView]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(whenFinishOtherUserVideo:) name:kVideoFinishNotification object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nightModeInOtherUserVideosVC) name:kNotificationNightMode object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refershOtherUserVideos) name:kRefreshUploadedVideoData object:nil]; 

    self.lblNoVideo.hidden = YES; 

    nMaxID = 0; 
    isNewVideosAvailable = false; 
    [self getOtherUserVideos:nMaxID]; 

    self.lblNavTitle.text = [NSString stringWithFormat:@"%@'s Videos", self.objOtherUser.strUserName]; 

    self.tblVW.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; 
    self.tblVW.separatorColor = [UIColor clearColor]; 

    refreshControl = [[UIRefreshControl alloc] init]; 
    if ([[SharedClass objSharedClass] isNightModeEnable]) { 
     [refreshControl setTintColor:[UIColor whiteColor]]; 
    } 
    else { 
     [refreshControl setTintColor:kAppThemeColor]; 
    } 
    [refreshControl addTarget:self action:@selector(refershOtherUserVideos) forControlEvents:UIControlEventValueChanged]; 
    [self.tblVW addSubview:refreshControl]; 

    self.tblVW.estimatedRowHeight = 278.0f; 
    self.tblVW.rowHeight = UITableViewAutomaticDimension; 

    //Set status bar 
    [self setNeedsStatusBarAppearanceUpdate]; 
} 


-(void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 
    self.tabBarController.tabBar.hidden = NO; 

    //CALL TO REMOVE ASSIGNED OBSERVER 
    [currentCell removeAssignedObserverToPlayerItem]; 
    [currentCell pause]; 
    [currentCell.loadingIndicatorView removeFromSuperview]; 
    [currentCell.btnPlayPause setSelected:false]; 
    [currentCell.seekSlider removeFromSuperview]; 
    currentCell.playerLayer.sublayers = nil; 
    currentCell.player = nil; 
    [currentCell unHideVideoControls]; 
    [self.arrPlayedVideo removeAllObjects]; 

    // To Hide Opened View More Option View 
    [arrSelectedIndexPath removeAllObjects]; 
} 


-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    if (arrOtherVideos.count <= 0) { 
     return 0; 
    } 
    else { 
     return arrOtherVideos.count; 
    } 
} 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *cellIdentifier = @"FeedSingleViewCell"; 

    FeedSingleViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 

    if (cell == nil) { 
     cell = [[[NSBundle mainBundle] loadNibNamed:cellIdentifier owner:self options:nil] objectAtIndex:0]; 
    } 

    UserVideoObject *objMyUploadedVideo = [arrOtherVideos objectAtIndex:indexPath.row]; 

    cell.vwMainBack.layer.cornerRadius = 3.0f; 
    cell.vwMainBack.clipsToBounds = YES; 

    cell.activityIndicator.hidden = YES; 
    cell.btnPlayPause.hidden = NO; 

    if ([arrAddedPlayerIndexPath containsObject:objMyUploadedVideo]) { 
     [cell.btnPlayPause setSelected:true]; 
    } 
    else { 
     [cell.btnPlayPause setSelected:false]; 
    } 

    if (objMyUploadedVideo.strVideoURL != nil) { 
     cell.isVideoAvailable = true; 
    } 
    else { 
     cell.isVideoAvailable = false; 
    } 

    UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onOtherUserVideosPlayerViewTap:)]; 
    gesture.numberOfTapsRequired = 1; 
    cell.playerView.tag = indexPath.row; 
    [cell.playerView addGestureRecognizer:gesture]; 

    cell.lblCurrentPlayTime.tag = indexPath.row; 
    cell.btnPlayPause.tag = indexPath.row; 
    [cell.btnPlayPause addTarget:self action:@selector(onOtherUserProfileVideoPlayPauseButtonClick:) forControlEvents:UIControlEventTouchUpInside]; 

    [cell.imgVWVideoCoverImage sd_setImageWithURL:[NSURL URLWithString:objMyUploadedVideo.strVideoCoverImage] placeholderImage:[UIImage imageNamed:@""]]; 

    cell.imgVWUserProfilePhoto.layer.cornerRadius = cell.imgVWUserProfilePhoto.frame.size.width/2.0f; 
    cell.imgVWUserProfilePhoto.clipsToBounds = YES; 

    [cell.imgVWUserProfilePhoto sd_setImageWithURL:[NSURL URLWithString:objMyUploadedVideo.strUserImage] placeholderImage:[UIImage imageNamed:kUserPlaceHolderImage]]; 

    cell.lblNumberOfViews.text = [NSString stringWithFormat:@"%@ Views", [[SharedClass objSharedClass] abbreviateNumber:objMyUploadedVideo.nVideoViews]]; 
    cell.lblVideoDuration.text = objMyUploadedVideo.strVideoLength; 

    if ([objMyUploadedVideo.strVideoCreatedTime isEqualToString:@""] || [objMyUploadedVideo.strVideoCreatedTime isKindOfClass:[NSNull class]] || objMyUploadedVideo.strVideoCreatedTime == nil) { 
     cell.lblVideoPostedDate.text = @""; 
    } 
    else { 
     cell.lblVideoPostedDate.text = [[SharedClass objSharedClass] convertDateStringToUTCDate:objMyUploadedVideo.strVideoCreatedTime]; 
    } 

    cell.lblVideoDescription.text = objMyUploadedVideo.strVideoTitle; 

    cell.vwVideoTime.layer.cornerRadius = 3.0f; 

    cell.vwMainBack.layer.borderWidth = 0.3; 
    cell.vwMainBack.layer.borderColor = [[[UIColor lightGrayColor] colorWithAlphaComponent:0.4] CGColor]; 

// UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onOtherUserUploadedProfilePhotoClick:)]; 
// tap.numberOfTapsRequired = 1; 
// cell.imgVWUserProfilePhoto.tag = indexPath.row; 
// [cell.imgVWUserProfilePhoto addGestureRecognizer:tap]; 

    cell.layer.shouldRasterize = YES; 
    cell.layer.rasterizationScale = [UIScreen mainScreen].scale; 

    cell.btnMore.tag = indexPath.row; 
    [cell.btnMore addTarget:self action:@selector(onOtherUserVideosMoreButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; 

    cell.btnHideVideo.tag = indexPath.row; 
    [cell.btnHideVideo addTarget:self action:@selector(onOtherUserVideoHideButtonClick:) forControlEvents:UIControlEventTouchUpInside]; 

    cell.vwMore.layer.cornerRadius = 3.0f; 
    cell.vwHide.layer.cornerRadius = 3.0f; 
    cell.vwRemoveOrUnHide.layer.cornerRadius = 3.0f; 

    if ([arrSelectedIndexPath containsObject:objMyUploadedVideo]) { 
     cell.vwHide.hidden = false; 
    } 
    else { 
     cell.vwHide.hidden = true; 
    } 

    if ([[SharedClass objSharedClass] isNightModeEnable]) { 
     [cell.btnPlayPause setImage:[UIImage imageNamed:@"playNightMode.png"] forState:UIControlStateNormal]; 
     [cell.btnPlayPause setImage:[UIImage imageNamed:@"pauseNightMode.png"] forState:UIControlStateSelected]; 
     cell.vwMainBack.backgroundColor = kNightModeAppThemeColor; 
     cell.vwVideoTime.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.7]; 
     cell.lblVideoDuration.textColor = [UIColor whiteColor]; 
     cell.lblVideoDescription.textColor = [UIColor whiteColor]; 
     cell.vwMore.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7]; 

     [cell.btnHideVideo setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 
     [cell.btnHideVideo setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected]; 

     [cell.btnMore setImage:[UIImage imageNamed:@"more_icon.png"] forState:UIControlStateNormal]; 
     [cell.btnMore setImage:[UIImage imageNamed:@"more_icon.png"] forState:UIControlStateSelected]; 
    } 
    else { 
     [cell.btnPlayPause setImage:[UIImage imageNamed:@"Play.png"] forState:UIControlStateNormal]; 
     [cell.btnPlayPause setImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateSelected]; 
     cell.vwMainBack.backgroundColor = kTabBarBGColor; 
     cell.vwVideoTime.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.7]; 
     cell.lblVideoDuration.textColor = kMainGrayColor; 
     cell.lblVideoDescription.textColor = kMainGrayColor; 
     cell.vwMore.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7]; 

     [cell.btnHideVideo setTitleColor:kMainGrayColor forState:UIControlStateNormal]; 
     [cell.btnHideVideo setTitleColor:kMainGrayColor forState:UIControlStateSelected]; 

     [cell.btnMore setImage:[UIImage imageNamed:@"more_icongray.png"] forState:UIControlStateNormal]; 
     [cell.btnMore setImage:[UIImage imageNamed:@"more_icongray.png"] forState:UIControlStateSelected]; 
    } 

    return cell; 
} 


-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    [self reloadCells:scrollView]; 
} 

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    [self reloadCells:scrollView]; 
} 

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 

} 

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 
    if (!decelerate) { 
     [self reloadCells:scrollView]; 
    } 
} 

# pragma mark - Video AutoPlay Call Method - 

-(void)reloadCells:(UIScrollView *)scrollView { 
    CGPoint currentOffset; 
    NSTimeInterval currentTime; 
    NSTimeInterval timeDiff; 

    currentOffset = scrollView.contentOffset; 
    currentTime = [NSDate timeIntervalSinceReferenceDate]; 
    timeDiff = currentTime - lastOffsetCapture; 

    if (timeDiff > 0.1) { 
     [self managePlay]; 
     lastOffset = currentOffset; 
     lastOffsetCapture = currentTime; 
    } 
} 

-(void)managePlay { 
    [self removeUnWantedCell]; 
    [self.arrAddedVideo removeAllObjects]; 

    for (FeedSingleViewCell *cell in self.tblVW.visibleCells) { 
     [self.arrAddedVideoCell addObject:cell]; 
     CGRect rectInSuperview; 
     CGFloat xPos; 
     CGFloat yPos; 
     CGPoint imgPoint; 
     NSIndexPath *indexPath = [self.tblVW indexPathForCell:cell]; 
     UserVideoObject *objMyUploadedVideo = [arrOtherVideos objectAtIndex:indexPath.row]; 

     NSString *foo = objMyUploadedVideo.strVideoURL; 
     NSString *bar = [foo stringByReplacingOccurrencesOfString:kServer1 withString:kServer2]; 

     rectInSuperview = [cell.playerView convertRect:cell.playerView.frame toView:self.view]; 
     xPos = self.imgviewCenter.frame.origin.x + self.imgviewCenter.frame.size.width; 
     yPos = self.imgviewCenter.frame.origin.y + self.imgviewCenter.frame.size.height; 
     imgPoint = CGPointMake(xPos, yPos); 

     if (CGRectContainsPoint(rectInSuperview, imgPoint)) { 
      [currentCell pause]; 
      [currentCell.loadingIndicatorView removeFromSuperview]; 
      [currentCell.btnPlayPause setSelected:false]; 
      [currentCell.seekSlider removeFromSuperview]; 
      currentCell.playerLayer.sublayers = nil; 
      currentCell.player = nil; 
      [currentCell unHideVideoControls]; 
      [self.arrPlayedVideo removeAllObjects]; 

      [self.arrPlayedVideo addObject:bar]; 
      [self.arrAddedVideo addObject:cell]; 

      [cell hideVideoControls]; 

      // FOR REMOVING OLD VIDEO LAYER 
      [cell pause]; 
      cell.playerLayer.sublayers = nil; 
      cell.player = nil; 

      tempCell = nil; 
      tempCell = [[FeedSingleViewCell alloc] init]; 
      currentCell = cell; 

      [self callOtherUserVideoViewsAPIInUserVideView:objMyUploadedVideo]; 
      [cell playVideoInCurrentCell:[NSURL URLWithString:bar]]; 
      [cell.loadingIndicatorView startAnimating]; 
     } 
     else { 

     } 
    } 
} 

-(void)removeUnWantedCell { 
    for (int i = 0; i < self.arrAddedVideoCell.count; i++) { 
     FeedSingleViewCell *cell = [self.arrAddedVideoCell objectAtIndex:i]; 
     if (cell.isVideoAvailable) { 
      // FOR REMOVING OLD VIDEO LAYER 
      [cell pause]; 
      [cell.loadingIndicatorView removeFromSuperview]; 
      [cell.btnPlayPause setSelected:false]; 
      [cell.seekSlider removeFromSuperview]; 
      cell.playerLayer.sublayers = nil; 
      cell.player = nil; 
      [cell unHideVideoControls]; 
     } 
    } 
} 

//REMOVE LAST PLAYED VIDEO USING POST NOTIFICATION 
-(void)whenFinishOtherUserVideo:(NSNotification *)notification { 
    NSDictionary *userInfo = [notification object]; 
    NSString *strURL = [userInfo valueForKey:@"videoURL"]; 

    // UNHIDE CONTROLLERS AFTER VIDEO FINISHED 
    currentCell.seekSlider.value = 0.0f; 
    [currentCell unHideVideoControls]; 
    currentCell.seekSlider.hidden = YES; 

    // CHECK WHICH VIDEO IS FINISH PLAYING, ONCE WE GOT THAT VIDEO OBJECT MAKE THAT VIDEO CMTIME TO 0, SO IT WILL PLAY FROM START UP POSITING WHEN USER CLICK 2ND TIME ON THAT TO PLAY THIS 
    for (int i = 0; i < arrOtherVideos.count; i++) { 
     UserVideoObject *objVideo = [arrOtherVideos objectAtIndex:i]; 
     NSString *strVideoURL = [objVideo.strVideoURL stringByReplacingOccurrencesOfString:kServer1 withString:kServer2]; 
     if ([strVideoURL isEqualToString:strURL]) { 
      objVideo.fVideoLastPauseTime = CMTimeMake(0, 0); 
     } 
    } 

    [self.arrPlayedVideo removeObject:strURL]; 
} 

FeedSingleViewCell.m文件視頻播放方法

# pragma mark - Initialize Movie Player & Play Current Video - 

-(void)playVideoInCurrentCell:(NSURL *)videoURL { 
    self.strSelectedVideoURL = [videoURL absoluteString]; 
    self.loadingIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    self.seekSlider = [[UISlider alloc] init]; 


// AVPlayer *player = [AVPlayer playerWithURL:videoURL]; 

    self.playerItem = [AVPlayerItem playerItemWithURL:videoURL]; 
    self.player = [AVPlayer playerWithPlayerItem:self.playerItem]; 
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 
    playerLayer.frame = self.playerView.bounds; 
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 

// self.player = player; 
    NSLog(@"PLAYER TAG = %@", self.player); 
    self.playerLayer = playerLayer; 
    [self.playerView.layer addSublayer:playerLayer]; 
    [self.playerView bringSubviewToFront:self.btnPlayPause]; 

    [self.btnPlayPause setSelected:true]; 
    [self.player play]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinishedCallback:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem]; 

    CMTime timeInterval = CMTimeMakeWithSeconds(1.0, 10); 

    double interval = .1f; 

    CMTime playerDuration = [self playerItemDuration]; // return player duration. 
    if (CMTIME_IS_INVALID(playerDuration)) { 

    } 

    double duration = CMTimeGetSeconds(playerDuration); 
    if (isfinite(duration)) { 
     CGFloat width = CGRectGetWidth([self.seekSlider bounds]); 
     interval = 0.5f * duration/width; 
    } 

    __weak typeof(self) weakSelf = self; 
    self.timeObserver = [self.player addPeriodicTimeObserverForInterval:timeInterval queue:dispatch_get_main_queue() usingBlock:^(CMTime elapsedTime) { 

     [weakSelf observeTime:elapsedTime]; 
     [weakSelf syncScrubber]; 
    }]; 

    CGFloat controlsHeight = 30; 
    CGFloat controlsY = self.playerView.bounds.size.height - controlsHeight; 
    self.seekSlider.frame = CGRectMake(5, controlsY, self.playerView.bounds.size.width - 10, controlsHeight); 
    self.loadingIndicatorView.center = self.playerView.center; 

    [self.playerView addSubview:self.seekSlider]; 
    [self.seekSlider addTarget:self action:@selector(sliderBeganTracking:) forControlEvents:UIControlEventTouchDown]; 
    [self.seekSlider addTarget:self action:@selector(sliderEndedTracking:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; 
    [self.seekSlider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged]; 

    self.loadingIndicatorView.hidesWhenStopped = true; 
    [self.playerView addSubview:self.loadingIndicatorView]; 

    [self.playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:playbackLikelyToKeepUpContext]; 
    [self.playerItem addObserver:self forKeyPath:@"rate" options:0 context:0]; 
} 

在這裏,我上傳我的全部代碼。

墜機的原因是什麼?

enter image description here

+0

集tempCell強參考 –

+0

@DSDharma我設置強屬性,它仍然將崩潰[FeedSingleViewCell保留]:消息發送到釋放實例0x7fee13830600 – Pankil

+0

設置你的所有類屬性具有較強的ref.The點是記憶中釋放。 –

回答

1

您需要添加或在您的tableViewCell的類改變。

由於觀察者依然存在,可能會發生此次崩潰。所以你需要手動刪除。

-(void)dealloc { 
     @try { 
      [self.playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"]; 
      [self.playerItem removeObserver:self forKeyPath:@"rate"]; 
      self.playerItem = nil; 
     }@catch(id anException) { 
      NSLog(@"Trending Video Remove Observer Exception = %@", anException); 
     } 
    } 
3

看起來你需要將下面的代碼添加到您的視圖控制器類:

- (void)dealloc { 
    currentCell = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

還要確保currentCell被聲明爲強或弱。

+0

它仍然會崩潰 – Pankil

+0

你可以顯示你的playVideoInCurrentCell:方法嗎? – Alexey

+0

好吧,我用這種方法更新我的問題。 – Pankil

0

嘗試刪除下面的委託屬性。

-(void) viewWillDisappear:(BOOL) animated 
{ 
    [super viewWillDisappear:animated]; 
    if ([self isMovingFromParentViewController]) 
    { 
     if (self.navigationController.interactivePopGestureRecognizer.delegate == self) 
     { 
      self.navigationController.interactivePopGestureRecognizer.delegate = nil; 
     } 
    } 
} 
+0

您是否看到我發佈的問題和錯誤? – Pankil

+0

Ofcourse,當控制器被釋放,但仍然是視圖控制器的代表時,可能會發生崩潰。你試過這個嗎? –

+0

是的,它嘗試這一點,但我們的解決方案是完全不同的,我沒有面臨這個問題。[FeedSingleViewCell retain]:消息發送到釋放實例0x7ffbb8950a00 – Pankil

相關問題