这是我关于stackoverflow的第一个问题。我正在开发一个iOS应用程序,它使用来自网络上MySQL服务器的数据。我创建了一个名为“DataController”的类,它完全管理同步进程,并使用NSURLConnection和委托来检索信息,解析它并将其存储在CoreData模型中。它在此过程中使用了几种方法,如下所示:
[self.dataControllerObject syncStudents]
syncStudents 被称为
- >从服务器获取下载列表
- >存储必须在NSArray-property中下载的所有元素的ID - >调用 syncNextStudentsyncNextStudent 被称为
- >从NSArray-property获取第一个元素 - >建立NSURLConnection以检索数据connectionDidFinishLoading 被称为
- >数据存储在CoreData中 - > ID从NSArray-property中删除 - >调用 syncNextStudentsyncNextStudent 最终没有数组元素并完成整个过程。
我希望我明确了这个功能。现在这是我的问题:
如何中止整个过程,例如当用户现在不想同步并点击某个按钮时?
我尝试创建DataController对象并使用[self performSelectorInBackground:@selector(startSyncing)withObject:nil]调用syncStudents方法另一个线程,但现在我的NSURLConnection不会触发任何委托方法。
我该怎么办?
提前致谢。
答案 0 :(得分:1)
您应该使用NSOperation
和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
答案 1 :(得分:0)
您可以做的是创建一个公开的BOOL 属性 doSync 。
每次打电话时
syncStudents被称为或 syncNextStudent被称为或 connectionDidFinishLoading
检查
if(doSync){
// *syncStudents is called* OR
// *syncNextStudent is called* OR
// *connectionDidFinishLoading*
}
不,您可以将doSync更改为 FALSE 以停止您的流程。
self.dataControllerObject.doSync = FALSE;