2013-07-17 332 views
1

我正在製作一個應用程序,顯示一個動畫UIImageView作爲指示應用程序繁忙的自定義方式。我正在使用NSOperationQueue進行文件上傳,我希望在隊列中有東西時顯示UIImageView。當隊列中的每個操作完成時,我想要刪除UIImageView。在NSOperationQueue完成後刪除動畫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的方式。

再次感謝!

+1

我沒有看到你的代碼中的任何地方,你刪除微調。如果你停止動畫,你應該有[self.spinnerView removeFromSuperview]; – rdelmar

+0

你有沒有看到我的答案? –

回答

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請求的實際工作是在它自己的線程上完成的。

寫你自己的併發NSOperation有點棘手,我自己寫了一個,但我可能應該剛剛使用AFNetworking。選項3可能是最快的,如果它滿足您的需求。

0

添加到您的.h文件中:UIImageView *spinnerView;在你的.m文件,你會希望這樣的事情在你-(void)newUpload

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