1

我已经看过很多主题,但我仍然无法弄清楚。

我有一个 UITableview 可以在线下载其内容。每个单元格都有一个图像,我使用 GCD 让图像下载。下载的图像将保存到磁盘,每次加载单元之前都会检查文件是否已存在,如果不存在 -> gcd、nsdata 等。

如果有人有良好的互联网连接(wifi),一切都会很好,但是如果我要在视图之间跳来跳去(来回),用我蹩脚的 3G 连接,会发生什么是它想要完成它的队列(大约4 个单元格),但已经分配了一个新单元格,一个新单元格,一个新单元格,最终用户必须等待很长时间才能执行其他单元格(他没有看到),然后才能填充实际的 UITableview。使用 NSLog 我可以看到,即使我在不​​同的视图中,它仍在下载和制作屏幕上可见的 uiimage。每个任务大约 100 kb,而且速度很慢(甚至没有互联网连接?!)如果你有很多可能需要一段时间。

我知道不可能取消它,但我在其他主题中阅读了有关使用 BOOL 变量的信息,但我并没有真正理解。即使当用户离开屏幕时 BOOL 变量发生变化,单元格已经在队列中,对吗?

是否有可能当用户点击我的导航控制器中的后退按钮,所以他离开视图时,我更改了队列中块使用的数据(清空它),所以没有什么可下载的,块将立即执行(没有什么可以做的)。就像,使数组newsitems中的每个值都为零?是否可以更改数据源,或者等待的块在等待时是否已经拥有它们的数据源?

然后还有一个问题,这对当前执行的块没有影响。

有人可以为我指出一个好的方向吗?

谢谢你。

普拉斯托

4

2 回答 2

1

您可以使用NSBlockOperationNSOperationQueue创建可取消的下载任务。你NSBlockOperation通过给它一个执行一些工作的块来创建一个。在您的情况下,该块将下载 URL 的内容。

在您的视图控制器中,您将存储已提交到队列的操作列表。如果用户决定离开当前视图,您可以调用cancel每个挂起的操作以防止发生任何不必要的工作。但是,当前正在运行的操作将运行完成。为了取消当前正在运行的操作,您需要在执行工作的块中存储对 NSOperation 对象的弱引用。然后在块体内的适当时间间隔,您可以检查操作是否已被取消并提前退出。

// Create a queue on which to run the downloads
NSOperationQueue* queue = [NSOperationQueue new];

// Create an operation without any work to do
NSBlockOperation* downloadImageOperation = [NSBlockOperation new];

// Make a weak reference to the operation. This is used to check if the operation
// has been cancelled from within the block
__weak NSBlockOperation* operation = downloadImageOperation;

// The url from which to download the image
NSURL* imageURL = [NSURL URLWithString:@"http://www.someaddress.com/image.png"];

// Give the operation some work to do
[downloadImageOperation addExecutionBlock: ^() {
    // Download the image
    NSData* imageData = [NSData dataWithContentsOfURL:imageURL];

    // Make sure the operation was not cancelled whilst the download was in progress
    if (operation.isCancelled) {
        return;
    }

    // Do something with the image
}];

// Schedule the download by adding the download operation to the queue
[queue addOperation:imageDownloadOperation];

// As necessary
// Cancel the operation if it is not already running
[imageDownloadOperation cancel];

今年在 WWDC 上就这个主题进行了一次很好的演讲,题为“在 iOS 上构建并发用户界面”。你可以在这里找到视频和幻灯片

于 2012-09-09T14:37:19.033 回答
0

我在不久前开发的应用程序中遇到了类似的问题,发现完成您需要的所有事情的最佳方法是使用https://github.com/MugunthKumar/MKNetworkKit

我花了一天中最好的时间来学习和理解转换,然后又花了几天时间将它调整到我所需要的。

如果您决定使用它或想要全面了解这些功能,请从这里开始 http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/

于 2012-09-09T10:12:46.300 回答