1

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

[self.dataControllerObject 同步学生]

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

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

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

syncNextStudent最终没有剩余数组元素并完成该过程。

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

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

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

我能做些什么?

提前致谢。

4

2 回答 2

1

你应该看看使用NSOperations 和 anNSOperationQueue而不是performSelectorInBackground:. 这使您可以更好地控制需要在后台执行的一批任务以及一次取消所有操作。这是我的建议。

将 a声明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
于 2013-02-13T18:05:07.213 回答
0

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

每当你的呼唤

调用了 syncStudents或调用了 syncNextStudentconnectionDidFinishLoading

检查

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

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

 self.dataControllerObject.doSync = FALSE;
于 2013-02-13T14:22:23.577 回答