- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序在离开 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];
}
我在这里上传我的完整代码。
崩溃的原因是什么?
最佳答案
看起来您需要将以下代码添加到您的 View Controller 类中:
- (void)dealloc {
currentCell = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
还要确保将 currentCell 声明为强或弱。
关于ios - 离开 UIViewController 时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44772546/
我希望能够在代码中布局我的 View Controller ,但可以看到界面构建器中显示的布局。 我知道我可以创建一个 UIView 子类,使其 IBDesignable,并将其分配给 View Co
我有一个父 UIViewController(MainVC)。从那里我有 2 个 segue 到 2 个 UIViewControllers:FirstVC(标识符:goFirstVC)和 Secon
我有一个导航 Controller 。第一个viewcontroller 是FirstViewController 的一种。当我在 FirstViewController 中点击一个按钮时,它会将第二
我有一个自定义的动画 UIViewController 过渡,似乎 iOS 中有一个错误会破坏横向布局。在主要动画方法中,我得到了横向和纵向 View 的混合。 (纵向 View 都是纵向的,所以没问
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我有一个 UIViewController,里面有 UITabBar。我正在尝试模仿 UITabBarController。 My question is how do I set or a UIVi
是否有任何方便的方法来确定是否正在从处于后台模式的应用加载 View ? 在 3.X 中,我将依赖 viewDidLoad 进行一些初始化等操作,但是对于 4.X 而言情况并非如此,因为您不能依赖调用
我将主视图 Controller 作为带有 UICollectionView 的 View Controller ,并且填充了照片。 一旦一个单元格被点击,一个新的 View Controller 被
我有一个简单的 UIViewController(单点触控),在 UI 上有一个按钮。现在,我的用例很简单 - 我想在单击按钮时重新加载 UIViewController。在某些线程上,我读到我只需要
我在它上面有一个 UIViewController 1 UIButton(添加为 subview ),在我按下 Button(见下面的图 1)之后,在它上面添加了另一个 UIViewControlle
尝试为 iPad 制作基于 Storyboard的应用程序。在其中,我需要从开始屏幕 (UIViewController) 过渡到主屏幕 (UISplitViewController),然后再到全屏
我想调整 UIViewController 的大小在 Storyboard中,所以我可以使用它的 UIViewController作为弹出 View 。 在大多数网站上,我可以读到这些操作是: 拖一个
我正在尝试从 XIB 或 Storyboard加载 ViewModel 绑定(bind)的 ViewController(使用 MvvmCross 5.0.6)。我的应用程序的逻辑是,该 View C
我正在构建一个锻炼应用程序。我的 TableViewController 中有一系列练习,每个单元格显示不同的练习。单元格转到 UIViewController。在 UIViewController
我正在尝试从 XIB 或 Storyboard加载 ViewModel 绑定(bind)的 ViewController(使用 MvvmCross 5.0.6)。我的应用程序的逻辑是,该 View C
我有一个 UIViewController,它有一个模式窗口,我想在整个界面上展示它,包括 UITabBar。 我的应用程序层次结构是这样的: UITabBarController (A) ->
我想显示另一个 ViewController 的缩小“预览”在另一个 ViewController .这可能吗?不需要交互,因此它基本上可以是屏幕截图,但按比例缩小。我可以通过手动截屏并将其保存为图像
我正在开发一个应用程序,其中 UIViewController ( firstViewController ) 包含一些 UILabels , 一个 UIButton , 和 UIView ( sub
我的标签栏中有五个标签栏项目。第五项是弹出ViewController。因此,当我单击该按钮时,当前 Controller 中将显示一个弹出窗口。我使用 UIViewController 作为子类来实
我正在开发 iOS 应用程序。 我的应用程序有 6 个按钮,每个按钮都有每个标签栏控件。 so Main screen is [btn1] [btn2] [btn3] [btn4] [btn5] [b
我是一名优秀的程序员,十分优秀!