将 NSOperationQueue 作为数据源发送到 UITableView
Posted
技术标签:
【中文标题】将 NSOperationQueue 作为数据源发送到 UITableView【英文标题】:Sending NSOperationQueue to UITableView as a DataSource 【发布时间】:2014-04-11 06:05:24 【问题描述】:我已经编写了使用NSOperationQueue
和NSOperation
从服务器下载数据的代码。现在我想在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的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 中上传时出现 NSOperationQueue(ASINetworkQueue) 问题