立即停止方法/对象吗?

问题描述:

这是我在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的不会触发任何委托方法。

我该怎么办?

在此先感谢。

你应该看看使用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

你可以做的是创建一个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