立即停止方法/对象?

时间:2013-02-13 14:13:14

标签: ios xcode multithreading

这是我关于stackoverflow的第一个问题。我正在开发一个iOS应用程序,它使用来自网络上MySQL服务器的数据。我创建了一个名为“DataController”的类,它完全管理同步进程,并使用NSURLConnection和委托来检索信息,解析它并将其存储在CoreData模型中。它在此过程中使用了几种方法,如下所示:

  

[self.dataControllerObject syncStudents]

     

syncStudents 被称为
   - >从服务器获取下载列表
   - >存储必须在NSArray-property中下载的所有元素的ID    - >调用 syncNextStudent

     

syncNextStudent 被称为
   - >从NSArray-property获取第一个元素    - >建立NSURLConnection以检索数据

     

connectionDidFinishLoading 被称为
   - >数据存储在CoreData中    - > ID从NSArray-property中删除    - >调用 syncNextStudent

     

syncNextStudent 最终没有数组元素并完成整个过程。

我希望我明确了这个功能。现在这是我的问题:

如何中止整个过程,例如当用户现在不想同步并点击某个按钮时?

我尝试创建DataController对象并使用[self performSelectorInBackground:@selector(startSyncing)withObject:nil]调用syncStudents方法另一个线程,但现在我的NSURLConnection不会触发任何委托方法。

我该怎么办?

提前致谢。

2 个答案:

答案 0 :(得分:1)

您应该使用NSOperationNSOperationQueue代替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

答案 1 :(得分:0)

您可以做的是创建一个公开的BOOL 属性 doSync

每次打电话时

syncStudents被称为 syncNextStudent被称为 connectionDidFinishLoading

检查

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

不,您可以将doSync更改为 FALSE 以停止您的流程。

 self.dataControllerObject.doSync = FALSE;