Iphone 正在后台线程中运行操作,是否有完成块?
我有一个任务是从磁盘读取数据,这可能需要相当长的时间,所以我不想在主线程中执行。。我想在从磁盘读取后调用函数X。在iOS中实现这一点的最佳方法是什么 到目前为止,我一直在尝试:Iphone 正在后台线程中运行操作,是否有完成块?,iphone,objective-c,ios,ipad,Iphone,Objective C,Ios,Ipad,我有一个任务是从磁盘读取数据,这可能需要相当长的时间,所以我不想在主线程中执行。。我想在从磁盘读取后调用函数X。在iOS中实现这一点的最佳方法是什么 到目前为止,我一直在尝试: NSInvocationOperation *processDataOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(readDisk:) object:nil]; [pro
NSInvocationOperation *processDataOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(readDisk:) object:nil];
[processDataOperation setQueuePriority:NSOperationQueuePriorityVeryHigh];
[processDataOperation setCompletionBlock:^(void){
NSMutableArray *feedItemsArray = [self generateFeedItemsFromDictionary:streamDiskData];
[self postFetchCompletedNotificationForDict:queryStringDict withFeedItems:feedItemsArray isFresh:NO];
}];
基本上,我使用NSInvocationOperation,然后设置它的完成块,但是问题是,在我的完成块中,我需要在readDisk中生成的结果。我如何在完成块中访问它?这几乎是不可能的,对吗?您可以随时使用grand central dispatch在后台执行操作 因为它是一个块,所以您可以正常调用该方法并存储结果。然后,如果需要更新任何UI或在完成后执行任何需要的操作,请抓取主队列
dispatch_queue_t queue = dispatch_queue_create("read disc", NULL);
dispatch_async(queue, ^{
result = [self readDisc];
dispatch_async(dispatch_get_main_queue(), ^{
//update UI or do whatever you need to do with the result of readDisc
});
});
dispatch_release(queue);
您可以使用grand central dispatch在后台执行操作 因为它是一个块,所以您可以正常调用该方法并存储结果。然后,如果需要更新任何UI或在完成后执行任何需要的操作,请抓取主队列
dispatch_queue_t queue = dispatch_queue_create("read disc", NULL);
dispatch_async(queue, ^{
result = [self readDisc];
dispatch_async(dispatch_get_main_queue(), ^{
//update UI or do whatever you need to do with the result of readDisc
});
});
dispatch_release(queue);
使用nsinvocation可以完成主线程之外的少量工作,但要复杂得多 GCD和NSOperations都可以用来实现广泛的并发策略。从面向对象的角度来看,NSO操作比CGD块更具高度抽象性,这使得它们(imo)更易于“设计”,并且可能在我实现它们的范围之外进行优化。GCD的级别较低:这使得与它的交互看起来稍微复杂一些(事实并非如此),但了解这类内容的人会告诉你,它“更高效”,而且“开销更小” 我个人的方法是在我的应用程序中有一个设计/编排的并发模式的场景中使用NSOperations,并在琐碎的并发/后台操作中使用GCD 如果我所需要做的只是启动一些与设计无关但需要在后台完成的任意任务,我会使用CGD。这就是我在这种情况下可能会用到的:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[self readDisk];
NSMutableArray *feedItemsArray = [weakSelf generateFeedItemsFromDictionary:streamDiskData];
dispatch_sync(dispatch_get_main_queue(), ^{
//Call back to the main thread before performing/posting anything touching UIKit
[self postFetchCompletedNotificationForDict:queryStringDict withFeedItems:feedItemsArray isFresh:NO];
})
})];
使用nsinvocation可以完成主线程之外的少量工作,但要复杂得多 GCD和NSOperations都可以用来实现广泛的并发策略。从面向对象的角度来看,NSO操作比CGD块更具高度抽象性,这使得它们(imo)更易于“设计”,并且可能在我实现它们的范围之外进行优化。GCD的级别较低:这使得与它的交互看起来稍微复杂一些(事实并非如此),但了解这类内容的人会告诉你,它“更高效”,而且“开销更小” 我个人的方法是在我的应用程序中有一个设计/编排的并发模式的场景中使用NSOperations,并在琐碎的并发/后台操作中使用GCD 如果我所需要做的只是启动一些与设计无关但需要在后台完成的任意任务,我会使用CGD。这就是我在这种情况下可能会用到的:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[self readDisk];
NSMutableArray *feedItemsArray = [weakSelf generateFeedItemsFromDictionary:streamDiskData];
dispatch_sync(dispatch_get_main_queue(), ^{
//Call back to the main thread before performing/posting anything touching UIKit
[self postFetchCompletedNotificationForDict:queryStringDict withFeedItems:feedItemsArray isFresh:NO];
})
})];
你已经试过什么代码了?你已经试过什么代码了?我想每个人都几乎同意NSO操作比GCD更可取?我认为你使用哪一种是真正的情景操作。当您只想设置一个块在代码中的某一点执行时,Grand Central Dispatch是很好的。NSOperation还有一些功能,您可以在代码的不同部分对其进行子类化和运行。GCD只是在您的情况下更容易获得后台操作的结果,并在主队列中使用它。我还认为使用iOS时GCD更好,因为NSOperation不像为mac编程时那样使用GCD。不利的一面是,最终可能会出现大量线程,这意味着操作系统必须不断切换。GCD将优化并向具有相同优先级e.t.c的现有队列中添加一个块,这可以节省处理电源和时间。我想每个人都几乎同意NSO操作比GCD更可取?我认为您使用的是真正的情景操作。当您只想设置一个块在代码中的某一点执行时,Grand Central Dispatch是很好的。NSOperation还有一些功能,您可以在代码的不同部分对其进行子类化和运行。GCD只是在您的情况下更容易获得后台操作的结果,并在主队列中使用它。我还认为使用iOS时GCD更好,因为NSOperation不像为mac编程时那样使用GCD。不利的一面是,最终可能会出现大量线程,这意味着操作系统必须不断切换。GCD将优化并向具有相同优先级e.t.c的现有队列中添加一个块,这可以节省处理电源和时间。我可以知道您为什么创建uuu unsafe uuu unretained weakSelf=self;不要直接在blokc内部使用self?当然-块将“复制”它引用的对象,从而声明所有权。这意味着self拥有块,但块也拥有self:这是retain循环的组成部分。通过在块中显式弱引用self,我们避免了这种可能性。因此,最佳做法是在块中使用self时使用弱引用?使用此代码,我得到一个错误,指向参数
DISPATCH\u QUEUE\u PRIORITY\u BACKGROUND
:“将'int'隐式转换为'DISPATCH\u QUEUE\t'(也称为'NSObject*”)不允许使用ARC“@NicolasMiari看到改进的答案,调度呼叫缺少访问后台队列的正确代码。请问您为什么创建了uuu unsafe uuu unretained weakSelf=self;不要直接在blokc内部使用self?当然-块将“复制”它引用的对象,从而声明所有权。这会让我