我的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
代表是否有以下代码:
if ([movie isDownloaded])
cell.detailTextLabel.text = movie.duration;
else
{
cell.detailTextLabel.text = @"";
[movie downloadInQueue:self.downloadQueue completion:^(BOOL success) {
UITableViewCell *updateCell = [tblView cellForRowAtIndexPath:indexPath];
if (updateCell)
{
updateCell.detailTextLabel.text = movie.duration;
[updateCell setNeedsLayout];
}
}];
}
调用Movie.m并运行此代码:
- (void)downloadInQueue:(NSOperationQueue *)queue completion:(void (^)(BOOL success))completion
{
if (!self.isDownloading)
{
self.downloading = YES;
[queue addOperationWithBlock:^{
BOOL success = NO;
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:self.fileURL];
CMTime timeduration = playerItem.duration;
float seconds = CMTimeGetSeconds(timeduration);
self.duration = [self timeFormatted:seconds];
self.downloading = NO;
self.downloaded = YES;
success = YES;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completion(success);
}];
}];
}
}
当我的单元格不可见时,我想取消NSOperation
对象中的Movie
(如果尚未运行)(从队列中删除) 。我知道我可以继承UITableViewCell
并做类似的事情:
- (void)willMoveToWindow:(UIWindow *)newWindow
{
[super willMoveToWindow:newWindow];
if (newWindow==nil) {
// Cell is no longer in window so cancel from queue
}
}
问题...如何从Movie
代表电话中取消NSOperation
UITableViewCell
?有代表或某种NSNotification
?我需要知道单元格的indexPath
才能从我的数组中获取正确的Movie对象并取消操作。
答案 0 :(得分:4)
从iOS 6开始,您可以使用UITableView Delegate protocol的tableView:didEndDisplayingCell:forRowAtIndexPath:方法。当从表视图中移除单元格时会调用此方法(当它不再可见时会发生)。
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// Cancel operation here for cell at indexPath
}
答案 1 :(得分:2)
顺便说一句,我刚刚在这里看到了这个问题,但已经回答了here。但我同意Nebs(他的回答应该被接受)。
正如Nebs所说,在iOS 6中,使用didEndDisplayingCell
。因此,它可能看起来像:
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
Movie *movie = self.movies[indexPath.row];
if ([movie isDownloading])
[movie cancelDownload];
}
但在早期版本中,你必须做一些事情,比如回复scrollViewDidScroll
,手动查看indexPath
中不再包含indexPathsForVisibleRows
个对象,并从那里取消操作
要取消操作,您需要更改此downloadInQueue
,以便不是仅调用addOperationWithBlock
,而是创建NSBlockOperation
并将其添加到队列中,保存weak
引用,以便您可以像这样编写cancelDownload
方法:
@interface Movie ()
@property (nonatomic, getter = isDownloaded) BOOL downloaded;
@property (nonatomic, getter = isDownloading) BOOL downloading;
@property (nonatomic, weak) NSOperation *operation;
@end
@implementation Movie
- (void)downloadInQueue:(NSOperationQueue *)queue completion:(void (^)(BOOL success))completion
{
if (!self.isDownloading)
{
self.downloading = YES;
NSOperation *currentOperation = [NSBlockOperation blockOperationWithBlock:^{
BOOL success = NO;
self.playerItem = [AVPlayerItem playerItemWithURL:self.webURL];
if (self.playerItem)
{
success = YES;
CMTime timeduration = self.playerItem.duration;
float seconds = CMTimeGetSeconds(timeduration);
self.durationText = [NSString stringWithFormat:@"%f", seconds];
}
self.downloading = NO;
self.downloaded = YES;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completion(success);
}];
}];
[queue addOperation:currentOperation];
self.operation = currentOperation;
}
}
- (void)cancelDownload
{
if ([self isDownloading] && self.operation)
{
self.downloading = NO;
[self.operation cancel];
}
}
@end
答案 2 :(得分:0)
看起来你应该将单元格或索引路径传递给downloadInQueue:completion:
。然后,您可以使用字典,数组或关联对象来维护单元格与其操作之间的连接。