NSOperationQueue完成后删除动画UIImageView

时间:2013-07-17 23:50:34

标签: ios uiimageview nsurlrequest nsoperationqueue

我正在创建一个应用程序,将动画UIImageView显示为指示应用程序正忙的自定义方式。我正在使用NSOperationQueue进行文件上传,我希望在队列中有东西时显示UIImageView。当队列中的每个操作完成时,我想删除UIImageView。

我认为这很容易做到,但过去一小时我一直被困住了。显示UIImageView非常简单,但我似乎无法删除它。这可能非常简单,我只是忽略了。这是我的代码。谢谢! :)

- (void)viewDidLoad {
    //set up the uiimageview
    self.spinnerView = [[UIImageView alloc] initWithFrame:CGRectMake([[UIScreen mainScreen] bounds].size.width-44,0,44,44)];
    self.spinnerView.animationImages = [NSArray arrayWithObjects:
                                     [UIImage imageNamed:@"0.gif"],
                                     [UIImage imageNamed:@"1.gif"],
                                     [UIImage imageNamed:@"2.gif"],
                                     [UIImage imageNamed:@"3.gif"],
                                     [UIImage imageNamed:@"4.gif"], nil];
    self.spinnerView.animationDuration = 0.5f;
    self.spinnerView.tag = 998;
    self.spinnerView.animationRepeatCount = 0;
    [self.view addSubview: self.spinnerView];

    //set up the queue
    self.uploadQueue = [[NSOperationQueue alloc] init];
    [self.uploadQueue setMaxConcurrentOperationCount:1];

    //set up observer for the queue
    [self.uploadQueue addObserver:self forKeyPath:@"operationCount" options:NSKeyValueObservingOptionNew context:NULL];
}


- (void)newUpload:(NSData*)data {
    [self.spinnerView startAnimating];
    //....
    //request is a NSURLRequest that's set up in this method
    [NSURLConnection sendAsynchronousRequest:request queue:self.uploadQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    }];
}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                     change:(NSDictionary *)change context:(void *)context
{
    if (object == self.uploadQueue && [keyPath isEqualToString:@"operationCount"]) {
        if (self.uploadQueue.operationCount == 0) {
            [self.spinnerView stopAnimating];
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object
                           change:change context:context];
    }

我这样做是否正确?有没有更好的方法呢?我已经被困在这里一段时间了,我开始认为可能不是UIImageView搞砸了,而是我将NSURLRequests添加到NSOperationQueue的方式。

再次感谢!

3 个答案:

答案 0 :(得分:2)

为什么不试试https://github.com/samvermette/SVProgressHUDhttps://github.com/jdg/MBProgressHUD?它们完全是为了这个目的而制作的(在做一些异步工作时显示模态加载窗口)。它们易于使用,可以轻松自定义图像和许多其他选项。

答案 1 :(得分:0)

将此添加到您的.h文件中:UIImageView *spinnerView;在您的.m文件中,您需要-(void)newUpload中的类似内容:

if (code that says file uploads are done) {
spinnerView.hidden = YES;
}

答案 2 :(得分:0)

sendAsynchronousRequest:queue:completionHandler:的文档说,只有在异步URL请求完成后,操作才会添加到指定的操作队列。此操作只是一个完成块。

所以我不认为你真正按照你想要的方式添加添加操作。 URL请求将在队列外部的自己的线程上运行,只有完成块放在队列中。如果你没有在完成块本身中指定任何内容,那么它甚至可能根本没有添加到队列中?

无论哪种方式,我都认为你没有向队列添加5个URL操作,然后用operationCount == 5,4,3,2,1,0逐个执行。你是更多可能会触发5个同时发出的URL请求,并且在URL请求完成后,它们的完成块会以不确定的顺序添加到队列中。


要做我认为你打算做的事,你可以:

  1. 编写包含和的“并发NSOperation子类 管理NSURLConnectionNSURLRequest
  2. 使用AFNetworking
  3. 继续sendAsynchronousRequest:queue:completionHandler:,但请使用。{ 启动下一个请求的一个操作的完成处理程序,以及 停止微调器的最终请求的完成处理程序。 你可以在这里使用主队列作为唯一的工作 在队列中开始下一个操作或停止微调器。无论如何,URL请求的实际工作都是在它自己的线程上完成的。
  4. 编写自己的并发NSOperation有点棘手,我自己写了一篇,但我可能应该只使用AFNetworking。如果满足您的需求,选项3可能是最快的。