2011-08-04 102 views
3

問題很簡單:我的應用程序控制是否每次啓動時都有更新。如果有更新,彈出窗口將顯示「是」或「否」選擇。當用戶點擊是4種方法啓動。這些方法下載xml文件並上傳CoreData。這是警報的代碼:iOS - 後臺進程和UI更新

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 

    if (buttonIndex==1) { 
     [self showActivityViewer]; 
     [self downloadControlAndUpdatePoi]; 
     [self downloadControlAndUpdateItinerari]; 
     [self downloadControlAndUpdateArtisti]; 
     [self downloadControlAndUpdateEventi]; 
     [self hideActivityViewer]; 
     NSLog(@"AGGIORNA"); 
    } else { 
     NSLog(@"NON AGGIORNARE"); 
     return; 
    } 
} 

但有一個問題:當用戶水龍頭是警告不會消失,並保留在屏幕上,直到所有的方法完成。所以我試試這個其他代碼:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 

    if (buttonIndex==1) { 
     [self showActivityViewer]; 
     [NSThread detachNewThreadSelector:@selector(startDownloads) toTarget:self withObject:nil]; 
     [self hideActivityViewer]; 
     NSLog(@"AGGIORNA"); 
    } else { 
     NSLog(@"NON AGGIORNARE"); 
     return; 
    } 
} 

-(void)startDownloads { 
    NSInvocationOperation *opPoi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdatePoi) object:nil]; 
    NSInvocationOperation *opItinerari=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateItinerari) object:nil]; 
    NSInvocationOperation *opArtisti=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateArtisti) object:nil]; 
    NSInvocationOperation *opEventi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateEventi) object:nil]; 
    NSArray *operations=[[NSArray alloc] initWithObjects:opPoi,opItinerari,opArtisti,opEventi, nil]; 
    NSOperationQueue *queue=[[NSOperationQueue alloc] init]; 
    [queue addOperations:operations waitUntilFinished:YES]; 
    [queue waitUntilAllOperationsAreFinished]; 

} 

甚至在這裏還有一個問題:我點擊開始,但活動查看器沒有出現。警報消失,線程開始並運行4種方法。

我需要在後臺運行的進程,就像我的第二代碼發生,但我需要我的showActityViewer方法將運行並顯示微調。

謝謝:)

回答

5

第一件事第一件事。您不需要啓動4個操作,因爲您已經在輔助線程中,並且不需要並行執行4個操作。你可以簡單地做:

-(void)startDownloads { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [self downloadControlAndUpdatePoi]; 
    [self downloadControlAndUpdateItinerari]; 
    [self downloadControlAndUpdateArtisti]; 
    [self downloadControlAndUpdateEventi]; 
    [pool release]; 
} 

首先,你需要在startDownloads定義一個自動釋放池,如果你使用的downloadControl*方法autorelease,否則我懷疑你將有泄漏。

至於爲什麼活動的指標顯示不出來,這取決於事實,你在呼喚:

[self hideActivityViewer]; 

分離之後。因此,您在顯示UI並將其刪除之前,UI已經有時間進行更新了。從那裏取出該行並重寫startDownloads這樣的:

-(void)startDownloads { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [self downloadControlAndUpdatePoi]; 
    [self downloadControlAndUpdateItinerari]; 
    [self downloadControlAndUpdateArtisti]; 
    [self downloadControlAndUpdateEventi]; 
    [self performSelectorOnMainThread:@selector(hideActivityViewer) withObject:nil waitUntilDone:NO]; 

    [pool release]; 
} 

這裏請注意,我打電話到主線程hideActivityViewer因爲只有主線程可以安全地使用UIKit。 編輯:

我不知道你在下載的方法,使用核心數據...

看一看Concurrency with Core Data。您至少需要爲您的輔助線程使用單獨的託管對象上下文來調整您的代碼(我不知道在那裏創建moc是否可行)。

也看看this tutorial from Cocoa is my Girlfriend

作爲替代一切,你可以考慮做:

if (buttonIndex==1) { 
    [self showActivityViewer]; 
    [self performSelector:@selector(startDownloads) withObject:nil afterDelay:0]; 
    NSLog(@"AGGIORNA"); 
} else { 
    NSLog(@"NON AGGIORNARE"); 
    return; 
} 

有:

-(void)startDownloads { 
    [self downloadControlAndUpdatePoi]; 
    [self downloadControlAndUpdateItinerari]; 
    [self downloadControlAndUpdateArtisti]; 
    [self downloadControlAndUpdateEventi]; 
    [self hideActivityViewer]; 
} 

這不使用線程所有,但我不知道該活動觀衆會顯示沒有任何故障。如果需要,還有一個級別的黑客,你可以指定延遲

[self performSelector:@selector(startDownloads) withObject:nil afterDelay:0.1]; 
+0

但我該如何調用startDownloads?在用戶點擊「是」之後,是否有NSThread分離或[自啓動下載]? –

+0

對不起,用detachThread;你正確地做到了這一點。唯一的一點是,在startDownloads中,你不需要更多的異步操作,它們可以是順序的。 – sergio

+0

似乎它是一切都好,但一個問題,大問題發生了:我的downloadAndControl *方法與CoreData一起工作,並與此解決方案我有一個NSInternalInconsistencyException與CoreData的方法保存。 –