立即停止方法/对象吗?
这是我在stackoverflow上的第一个问题。我正在研究使用网络上MySQL服务器的数据的iOS应用程序。我创建了一个名为“DataController”的类,该类完全管理同步过程,并使用NSURLConnection和委托来检索信息,解析并将其存储在CoreData模型中。它使用在这个过程中的几种方法,如:立即停止方法/对象吗?
[self.dataControllerObject syncStudents]
syncStudents被称为
- >会从服务器下载列表
- >存储的ID对于那些在NSArray的属性要下载的所有元素
- >调用syncNextStudentsyncNextStudent称为
- >获得第一元素从NSArray的属性
- >堆积NSURLConnection的检索数据connectionDidFinishLoading称为
- >数据存储在CoreData
- - >调用syncNextStudentsyncNextStuden - > 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
你可以做的是创建一个BOOL 属性doSync这是公开的。
,当你调用
syncStudents被称为或syncNextStudent被称为或connectionDidFinishLoading
支票
if(doSync){
// *syncStudents is called* OR
// *syncNextStudent is called* OR
// *connectionDidFinishLoading*
}
不,你可以改变doSync每次FALSE停止你的过程。
self.dataControllerObject.doSync = FALSE;
我试过了,但属性值在运行过程中没有改变。 – 2013-02-13 20:26:45
谢谢你的回答,学到了一些新东西!一个问题:我应该如何在这个结构中访问CoreData?是否每个_StudentOperation_对象都有自己的NSManagedObjectModel,NSPersistantStoreCoordinator等?如果没有(我认为是这样),如果只有_DataController_有它们,那么访问它们最好的是什么? – 2013-02-14 08:51:05
您只需要一个持久性存储协调器和一个托管对象模型,但是,您需要在后台线程中处理返回的数据,这意味着您需要在后台线程中创建一个NSManagedObjectContext,以用于执行导入。一旦完成导入,您必须保存该上下文并通知您的主要更新上下文。另外,请看看mogenerator(http://rentzsch.github.com/mogenerator/),它会根据您的CoreData模型自动生成托管对象。我建议你问一个单独的具体问题,以获得更多的细节。 – 2013-02-14 17:22:52