2013-02-13 65 views
1

這是我在stackoverflow上的第一個問題。我正在研究使用網絡上MySQL服務器的數據的iOS應用程序。我創建了一個名爲「DataController」的類,該類完全管理同步過程,並使用NSURLConnection和委託來檢索信息,解析並將其存儲在CoreData模型中。它使用在這個過程中的幾種方法,如:立即停止方法/對象嗎?

[self.dataControllerObject syncStudents]

syncStudents被稱爲
- >會從服務器下載列表
- >存儲的ID對於那些在NSArray的屬性要下載的所有元素
- >調用syncNextStudent

syncNextStudent稱爲
- >獲得第一元素從NSArray的屬性
- >堆積NSURLConnection的檢索數據

connectionDidFinishLoading稱爲
- >數據存儲在CoreData
- - >調用syncNextStudent

syncNextStuden - > ID從NSArray的屬性
除去t
最終沒有剩下數組元素並完成該過程。

我希望我明確了功能。現在這是我的問題:

如何中止整個過程,例如當用戶不想現在同步並點擊某個按鈕?

我試圖創建DataController類對象,並調用syncStudents方法的使用另一個線程[自performSelectorInBackground:@selector(startSyncing)withObject:無],但現在我的NSURLConnection的不會觸發任何委託方法。

我該怎麼辦?

在此先感謝。

回答

0

你應該看看使用NSOperation S和一個NSOperationQueue而不是performSelectorInBackground:。這使您可以更好地控制需要在後臺執行的一批任務,以及一次取消所有操作。這是我的建議。

聲明一個NSOperationQueue作爲屬性

@property (nonatomic, retain) NSOperationQueue *operationQueue; 

然後在實現文件中實例化它:

_operationQueue = [[NSOperationQueue] alloc] init]; 

創建NSOperation派生類,將做處理。

@interface StudentOperation : NSOperation 

// Declare a property for your student ID 
@property (nonatomic, strong) NSNumber *studentID; 

@end 

然後迭代你創建操作的任何集合。

for (NSSNumber *studentID in studentIDs) { // Your array of ids 
    StudentOperation *operation = [[StudentOperation alloc] init]; 

    // Add any parameters your operation needs like student ID 
    [operation setStudentID:studentID]; 

    // Add it to the queue 
    [_operationQueue addOperation:operation]; 
} 

如果要取消,只是告訴操作隊列:

[_operationQueue cancelAllOperations]; 

請記住,這將立即取消正在排隊是當前未進行處理任何操作。如果您想停止當前正在運行的任何操作,則必須將代碼添加到您的NSOperation派生類(上面的StudentOperation)中,以檢查此類操作。所以,說你的NSOperation代碼正在運行它的main()函數。您需要定期檢查並確定cancelled標誌是否已設置。

@implementation StudentOperation 

- (void)main 
{ 
    // Kick off your async NSURLConnection download here. 
    NSURLRequest *theRequest = [NSURLRequest requestWithURL... 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

    // ... 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    // Append the data 
    [receivedData appendData:data]; 

    // Check and see if we need to cancel 
    if ([self isCancelled]) { 
     // Close the connection. Do any other cleanup 

    } 
} 

@end 
+0

謝謝你的回答,學到了一些新東西!一個問題:我應該如何在這個結構中訪問CoreData?是否每個_StudentOperation_對象都有自己的NSManagedObjectModel,NSPersistantStoreCoordinator等?如果沒有(我認爲是這樣),如果只有_DataController_有它們,那麼訪問它們最好的是什麼? – 2013-02-14 08:51:05

+0

您只需要一個持久性存儲協調器和一個託管對象模型,但是,您需要在後臺線程中處理返回的數據,這意味着您需要在後臺線程中創建一個NSManagedObjectContext,以用於執行導入。一旦完成導入,您必須保存該上下文並通知您的主要更新上下文。另外,請看看mogenerator(http://rentzsch.github.com/mogenerator/),它會根據您的CoreData模型自動生成託管對象。我建議你問一個單獨的具體問題,以獲得更多的細節。 – 2013-02-14 17:22:52

0

你可以做的是創建一個BOOL 屬性doSync這是公開的。

,當你調用

syncStudents被稱爲syncNextStudent被稱爲connectionDidFinishLoading

支票

if(doSync){ 
    // *syncStudents is called* OR 
    // *syncNextStudent is called* OR 
    // *connectionDidFinishLoading* 
} 

不,你可以改變doSync每次FALSE停止你的過程。

self.dataControllerObject.doSync = FALSE; 
+0

我試過了,但屬性值在運行過程中沒有改變。 – 2013-02-13 20:26:45