2

是我的- (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 NSOperationUITableViewCell代表呼叫中取消我的?与代表或NSNotification某种形式?我需要知道indexPath单元格以从我的数组中获取正确的 Movie 对象并取消操作。

4

3 回答 3

4

从 iOS 6 开始,您可以使用UITableView 委托协议的 tableView:didEndDisplayingCell:forRowAtIndexPath: 方法。当单元格从表格视图中移除时会调用它(当它不再可见时会发生这种情况)。

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    // Cancel operation here for cell at indexPath
}
于 2013-01-20T22:58:55.593 回答
2

顺便说一句,我刚刚在这里看到了这个问题,但已经在这里回答了。但我同意内布斯(他的回答应该被接受)。

正如 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,它应该创建 aNSBlockOperation并将其添加到队列中,但还要保存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
于 2013-01-20T23:53:32.113 回答
0

看起来您应该将单元格或索引路径传递给downloadInQueue:completion:. 然后,您可以使用字典、数组或关联对象来维护单元格及其操作之间的连接。

于 2013-01-20T23:01:48.037 回答