0

您将如何阻止程序执行?睡眠功能不这样做吗?如果是这样,这段代码有什么问题:

AsyncImageView *tmpImage = [imagesArray objectAtIndex:index];

int waitCounter = 0;
while (waitCounter < 10 && !tmpImage.imageIsLoaded) {
    waitCounter++;
    sleep(0.5);
}
NSLog(@"%i",waitCounter);
if (tmpImage.imageIsLoaded) {
    return [tmpImage image];
} else {
    return [UIImage imageNamed:@"img_noimg.png"];
}

AsyncImageView 类从 URL 加载图像,然后将 imageIsLoaded 属性设置为 true。这通常发生得很快(不到一秒钟),但是如果我像疯子一样滚动图像,那么它没有时间加载(它会提前加载 10 个图像)。

我添加了 while 以防止这种情况发生,但日志显示多个 waitCounter 为 10 的情况,而没有睡眠时间(界面没有冻结)。

4

3 回答 3

1

解决此类问题的一种方法是使用完成处理程序。当异步任务完成时,完成处理程序向调用站点发出信号,并将任务的结果作为参数传递给完成处理程序。

您的AsyncImageView班级确实有这样的完成处理程序。这是一个选择器。今天,人们会改用块。不过原理是一样的。

在异步任务完成后继续称为“继续”。使用块,您的代码如下所示:

typedef void (^completion_handler_block)(id result);

void doSomethingAsync(completion_handler_block)completionHandler;

- (void) foo {

    doSomethingAsync(^(id result) {
        // Continuation code
        ...
    });

}

使用块实现延续特别容易,因为它将上下文(在调用站点中定义的引用变量)保留在块(闭包)中。

于 2013-08-30T09:26:52.103 回答
0

你在哪里做这个?在方法cellForRowAtIndexPath中?

如果是这样,你不能睡在这里。

要异步加载图像,您必须

1)将真实的 UIImageView 传递给您的 AsyncImageView 和

2) 当你从 URL 加载 UIImage 时,而不是设置 *_imageIsLoaded = TRUE*,你可以使用 *_imageView.image = image* 直接在传递的 UIImageView 中加载它

例如,您可以这样做,考虑到您可能已经加载了图像等。像这样在 AsyncImageView 中创建此方法

-(void) reloadWithImageView:(UIImageView*)imageView {
    _imageView = imageView;
}

当您稍后加载 UIImage 时(可能在connectionDidFinishLoading方法中)

- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection {
    connection = nil;

    UIImage *image = [UIImage imageWithData:data];
    _imageView.image = image;
}
于 2013-08-30T09:46:13.790 回答
-1

试试这个,我想它会工作的。代替

sleep(0.5);

尝试

[NSThread sleepForTimeInterval:.5f];
于 2013-08-30T09:01:39.637 回答