gpt4 book ai didi

ios - 离开 UIViewController 时应用程序崩溃

转载 作者:行者123 更新时间:2023-11-28 18:49:39 28 4
gpt4 key购买 nike

我的应用程序在离开 UIViewController 时崩溃并出现以下错误。

[FeedSingleViewCell retain]: message sent to deallocated instance0x7ffbb8950a00

在我的 UIViewController 中,我使用了 UITableView 并且有自动播放功能,当视频结束或用户离开当前 UIViewController 时,在 ViewWillDisAppear 我将 AVPlayer 设为 nil,删除 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

最佳答案

看起来您需要将以下代码添加到您的 View Controller 类中:

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

还要确保将 currentCell 声明为强或弱。

关于ios - 离开 UIViewController 时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44772546/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com