我目前正在使用带有GCD队列的同步ASIHTTPRequest从Internet下载数据,然后使用JSONKit解析响应数据.您如何看待这种模式?先感谢您.
这是我的代码:
dispatch_async(queue, ^(void) {
// Request is ASIHTTPRequest.
[request startSynchronous];
// Parse JSON.
NSArray *array = [[request responseData] objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode];
// Callback on the main queue to update UI.
dispatch_async(dispatch_get_main_queue(), ^(void) {
callbackBlock(array);
});
});
Run Code Online (Sandbox Code Playgroud)
编辑:我使用ASIHTTPRequest的原因是我需要修改OAuth的请求标头并使用POST方法上传图像.
我想在循环时让队列等待一小段时间.我正在考虑我的选择,并试图暂停恢复队列,但这似乎需要几个移动部件.所以我正在考虑使用睡眠或睡眠.这更像是一般的线程函数,并且想知道我是否应该避免使用睡眠而是坚持使用GCD选项来使队列暂停.
我发现了一个相关问题,但答案显示他只是错过了一个包含.将GALL队列中的睡眠呼叫混合在一起有什么问题吗?
如何使用GCD定期在后台运行代码块?我正在尝试编写一个带有几个子系统的游戏引擎,如渲染,物理,游戏逻辑等.有些任务应该是事件驱动的,但是有些任务(比如物理系统)应该在后台以恒定时间周期性地调用(例如在1/100秒之后).我创建了一个代码块,但是如何在后台定期运行此块?GCD是正确的工具吗?
我将一些NSOperation代码转换为ARC时遇到了困难.我的操作对象使用完成块,该完成块又包含一个GCD块,用于更新主线程上的UI.因为我从自己的完成块中引用了我的操作对象,所以我使用__weak指针来避免内存泄漏.但是,在我的代码运行时,指针已经设置为nil.
我把它缩小到这个代码示例.谁知道我哪里出错了,以及正确的方法来实现这一目标?
NSOperationSubclass *operation = [[NSOperationSubclass alloc] init];
__weak NSOperationSubclass *weakOperation = operation;
[operation setCompletionBlock:^{
dispatch_async( dispatch_get_main_queue(), ^{
// fails the check
NSAssert( weakOperation != nil, @"pointer is nil" );
...
});
}];
Run Code Online (Sandbox Code Playgroud) objective-c nsoperation grand-central-dispatch objective-c-blocks automatic-ref-counting
首先,我创建一个这样的串行队列
static dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
Run Code Online (Sandbox Code Playgroud)
然后,在某个未知的时间点,任务会像这样添加到队列中
dispatch_async(queue, ^{
// do something, which takes some time
});
Run Code Online (Sandbox Code Playgroud)
如果第一个任务尚未完成,则新任务将等到第一个任务完成(当然这是串行队列的用途).
但是如果我向队列中添加5个新任务,而原来的第一个任务仍然在运行,我不想执行新的任务1,然后是2号,然后是3号,依此类推,但是想要获得删除任务1到4,并在原始第一个任务完成后直接开始执行任务5.
换句话说,如果我添加一个新任务,我想要从队列中弹出任何等待任务(不是当前正在运行的任务).
是否有内置机制或我是否必须自己实现?对于后者,我如何识别队列中的单个任务并将其删除?
这段代码
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"Main Thread? %d", [NSThread isMainThread]);
});
Run Code Online (Sandbox Code Playgroud)
表明我在主线程中.即使这样做:
queue = dispatch_queue_create("nonMainQueue", NULL);
Run Code Online (Sandbox Code Playgroud)
仍然报告说我在主队列中.这似乎是因为我正在使用dispatch sync.
这是否意味着我的代码与不使用dispatch_sync相同?另外:如果dispatch_sync什么都不做的话,那又有什么意义呢?
我想包装一个如下所示的异步API:
[someObject completeTaskWithCompletionHandler:^(NSString *result) {
}];
Run Code Online (Sandbox Code Playgroud)
进入一个我可以像这样调用的同步方法
NSString *result = [someObject completeTaskSynchronously];
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?我做了一些文档阅读和谷歌搜索,并尝试使用"dispatch_semaphore"尝试实现它,如下所示:
-(NSString *) completeTaskSynchronously {
__block NSString *returnResult;
self.semaphore = dispatch_semaphore_create(0);
[self completeTaskWithCompletionHandler:^(NSString *result) {
resultResult = result;
dispatch_semaphore_signal(self.semaphore);
}];
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
return resultResult;
}
Run Code Online (Sandbox Code Playgroud)
但这似乎没有用,它基本上只是停在dispatch_semaphore_wait.执行永远不会到达执行_signal的内部块.任何人都有关于如何做到这一点的代码示例?我怀疑该块必须在主线程的其他线程上?此外,假设我无法访问异步方法背后的源代码.谢谢!
multithreading asynchronous objective-c grand-central-dispatch ios
我一直在努力,但我只是不明白.我对编程很陌生,所以几乎每一个新步骤都是一个实验.虽然在没有参数/返回的情况下调度普通闭包没有问题,但到目前为止我还没有理解如何处理带有(多个)参数并最终返回的函数.
为了获得正确的"解决方案"的逻辑,如果有人能够发布一个实际的例子,那将是很好的,所以我可以看到我是否已经完全正确.我会非常感谢任何帮助...如果其他一些实际例子以更好的方式说明了这个话题,请继续自己做!
假设我们想要将以下函数异步调度到具有低优先级的后台队列(或者我犯了错误,在定义函数时尝试实现调度而不是等到从其他地方调用它?!):
func mutateInt(someInt: Int) -> Int {
"someHeavyCalculations"
return result
}
Run Code Online (Sandbox Code Playgroud)
或者是一个带有多个参数的函数,它还会在某个时刻调用第一个函数(后台队列中的所有内容):
func someBadExample(someString: String, anotherInt: Int) -> Int {
"someHeavyStuff"
println(testString)
mutateInt(testInt)
return result
}
Run Code Online (Sandbox Code Playgroud)
或者应该确保在主队列上运行的UI函数(只是一个虚构的例子):
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections?[section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
}
Run Code Online (Sandbox Code Playgroud) 我有一个大型数组,我想通过将它的片段交给几个异步任务来处理.作为概念证明,我编写了以下代码:
class TestParallelArrayProcessing {
let array: [Int]
var summary: [Int]
init() {
array = Array<Int>(count: 500000, repeatedValue: 0)
for i in 0 ..< 500000 {
array[i] = Int(arc4random_uniform(10))
}
summary = Array<Int>(count: 10, repeatedValue: 0)
}
func calcSummary() {
let group = dispatch_group_create()
let queue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
for i in 0 ..< 10 {
dispatch_group_async(group, queue, {
let base = i * 50000
for x in base ..< base + 50000 {
self.summary[i] += self.array[x]
}
})
}
dispatch_group_notify(group, …Run Code Online (Sandbox Code Playgroud) class SomeViewController: UIViewController {
let semaphore = DispatchSemaphore(value: 1)
deinit {
semaphore.signal() // just in case?
}
func someLongAsyncTask() {
semaphore.wait()
...
semaphore.signal() // called much later
}
}
Run Code Online (Sandbox Code Playgroud)
如果我告诉信号量等待,然后在信号量被告知发出信号之前取消初始化拥有它的视图控制器,则应用程序会因错误而崩溃Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)。但是,如果我只是调用视图控制器的方法,就可以避免灾难semaphore.signal()。deinit但是,如果异步函数在deinit调用之前返回并且视图控制器被取消初始化,则signal()调用两次,这似乎没有问题。但这样做安全和/或明智吗?