将 NSOperationQueue 作为数据源发送到 UITableView

Posted

技术标签:

【中文标题】将 NSOperationQueue 作为数据源发送到 UITableView【英文标题】:Sending NSOperationQueue to UITableView as a DataSource 【发布时间】:2014-04-11 06:05:24 【问题描述】:

我已经编写了使用NSOperationQueueNSOperation 从服务器下载数据的代码。现在我想在UserInterface 上显示进度。我使用UITableView 并使用NSOpeartionQueue 作为tableview 委托中的数据源

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
   return [[[Downloadmanager sharedInstance] downloadOperationQueue] count];    

并将 NSOperation 的属性绑定到 UITableViewCell。

1) 这是将NSOperationQueue 作为数据源发送到tableview 委托的可行解决方案吗? 2)NSOperation的状态变化时如何实现通知重新加载tableview?

谢谢。

【问题讨论】:

您的问题有更新吗?您发现任何有用的解决方案了吗? 嗨,谢谢。不,我实际上没有找到任何解决方案,情况是 - 我创建了一个操作说 PDOperation 在 PDOperationQueue 上运行,并且在其中我放置了一个 NSOperationQueue 并将操作说 PDChunkOperation 添加到这个队列中。 PDOperation 用于计算数据(从数据库中获取),将文件从 Asset 复制到文档目录,然后对文件进行加密,PDChunkOperation 用于以 PDChunkOperation 的形式上传文件。现在的问题是操作的重新分配。 并且要求 setMaxConcurrentOperationCount 对两个队列都说 2。我跟踪块操作的进度到 PDChunkOperationQueue(NSOperationQueue 的子类)。 哇,谁,所以你把队列放在队列中?是不是有点矫枉过正?必须有一种方法来扁平化该层次结构 - 使其成为一个队列...... 我在 NSoperation 中放入一个队列!!。现在好吗?我的重新分配问题解决了.... 【参考方案1】:

    我认为这不是使用NSOperationQueue 作为tableview 的数据源来显示进度的正确方法。您可以使用AFNetworking 等网络库下载数据,并使用setDownloadProgressBlock: 方法显示进度。请参考此链接获取代码download progress。

    下载完成后重新加载tableview很简单,在completionblock中调用[tableView reloadData]即可。

这是显示使用 AFNetworking 下载图像的代码,您可以轻松更改它以进行数据下载。(请参阅gist)

 - (void)downloadMultiAFN 
    // Basic Activity Indicator to indicate download
    UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    [loading startAnimating];
    [self.imageView.superview addSubview:loading];
    loading.center = self.imageView.center;

    // Create a request from the url, make an AFImageRequestOperation initialized with that request
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.picUrl]];
    AFImageRequestOperation *op = [[AFImageRequestOperation alloc] initWithRequest:request];

    // Set a download progress block for the operation
    [op setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) 
        if ([op.request.URL.absoluteString isEqualToString:@"http://www.pleiade.org/images/hubble-m45_large.jpg"]) 
            self.progressBar.progress = (float) totalBytesRead/totalBytesExpectedToRead;
         else self.progressBar2.progress = (float) totalBytesRead/totalBytesExpectedToRead;
    ];

    // Set a completion block for the operation
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) 
        self.imageView.image = responseObject;
        self.image = responseObject;
        if ([op.request.URL.absoluteString isEqualToString:@"http://www.pleiade.org/images/hubble-m45_large.jpg"]) 
            self.progressBar.progress = 0;
         else self.progressBar2.progress = 0;

     failure:^(AFHTTPRequestOperation *operation, NSError *error) ];

    // Start the image download operation
    [op start];

    // Remove the activity indicator
    [loading stopAnimating];
    [loading removeFromSuperview];

【讨论】:

感谢您的回答。但我不能使用这些库。【参考方案2】:

这是一个有趣的想法,但我认为创建这样一个“高耦合”——将模型与视图如此紧密地联系起来并不是一个好习惯。

我会处理它 - 像你已经做的那样在后台线程上下载数据 - 使用 NSOperationQueue 但将其保存到某种对象;比如NSMutableArray,它作为表格视图的数据源。

每次单个操作结束时(使用完成处理程序或 KVO 获取通知)- 更新表视图。更新可以通过两种方式完成 - 重新加载 更新。我将把选择权留给你 - 你可以在this question 阅读更多关于此的讨论。

【讨论】:

感谢 Michal,如果我创建一个类 (NSObjec) 并将 NSOperation 的进度添加到该类中并将该对象添加到 NSMutableArray 中,即在 Downloader 类中声明,这是正确的解决方案吗?? 另一个问题是 NSoperation 的子类 - 没有调用 dealloc。所以请给我提示,以便我知道这一点 很抱歉,我无法像这样为您提供帮助。我得看看代码。

以上是关于将 NSOperationQueue 作为数据源发送到 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

NSOperationQueue 用于同步上传

在 iOS 中上传时出现 NSOperationQueue(ASINetworkQueue) 问题

我可以将 spark 数据帧作为参数发送给 pandas UDF

NSOperationQueue

NSOperationQueue 和内存

NSOperationQueue 与 pthread 优先级