如何在GCD队列上停止/取消/暂停/恢复任务
如何停止后台队列操作?我想在我们的应用程序中停止一些屏幕.有些屏幕应该是自动恢复.那么,如何在iOS中传递队列?
我的意思是当用户浏览应用程序时,我们在dispatch_queue_t中运行后台线程.但它永远不会停止并在代码中恢复.那么如何暂停和恢复队列
我阅读了一些关于块和快速枚举以及GCD等的文章.@Bbum,他写了许多关于GCD和块主题的文章,他说块枚举方法总是比快速枚举方法快或快.你可以在这里阅读他的推理.
虽然这是一次引人入胜的智力对话,但我同意那些说它确实取决于手头任务的人.
我有一些任务需要完成,我需要快速,便宜,高效地完成这些任务.Apple为我们想要枚举数组的方式提供了很多选择,但我不确定选择哪个.
for (id obj in array)
{
/* Do something with |obj|. */
}
Run Code Online (Sandbox Code Playgroud)
[array enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
/* Do something with |obj|. */
}];
Run Code Online (Sandbox Code Playgroud)
[array enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
/* Do something with |obj|. */
}];
Run Code Online (Sandbox Code Playgroud)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_apply([array count], queue, ^(size_t idx) {
id obj = [array objectAtIndex: idx];
/* Do something with …Run Code Online (Sandbox Code Playgroud) arrays enumeration objective-c grand-central-dispatch objective-c-blocks
关于GCD创建了多少个线程,是否有任何好的文档?在WWDC,他们告诉我们它是围绕CPU核心建模的.但是,如果我称这个例子:
for (int i=1; i<30000; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[NSThread sleepForTimeInterval:100000];
});
}
Run Code Online (Sandbox Code Playgroud)
它打开66个线程,即使在iPad1上也是如此.(当本地调用Lion时,它还打开66个线程).为什么66?
我正在关注斯坦福大学的 CS193p 开发 iOS 应用程序在线课程。
它使用 Grand Central Dispatch (GCD) API 来演示多线程。但他们指出,
“自 WWDC 2021 起,GCD 已大部分被 Swift 新的内置异步 API 取代”。
因此,我想了解讲座中的代码在更新以使用这个新 API 后会是什么样子。
观看 Apple 的 WWDC 视频后,在我看来,
DispatchQueue.global(qos: .userInitiated).async { }这个新的异步 API 中被替换为Task { }或Task(priority: .userInitiated) {},但我不确定,被DispatchQueue.main.async { }替换为什么?
所以,我的问题是:
DispatchQueue.global(qos: .userInitiated).async { }已被替换为Task(priority: .userInitiated) {}DispatchQueue.main.async { }取代了?请帮忙,我想学习这个新的 async-await API。
以下是讲座中的代码,使用旧的 GCD API:
DispatchQueue.global(qos: .userInitiated).async {
let imageData = try? Data(contentsOf: url)
DispatchQueue.main.async { …Run Code Online (Sandbox Code Playgroud) 我有一些方法可以在某些情况下改变UI.
例如:
-(void) myMethod {
if(someExpressionIsTrue) {
// make some UI changes
// ...
// show actionSheet for example
}
}
Run Code Online (Sandbox Code Playgroud)
有时从某些人那里myMethod调用.mainThreadother thread
这就是为什么我希望这些UI更改可以肯定地执行mainThread.
我改变了myMethod这种方式所需的部分:
if(someExpressionIsTrue) {
dispatch_async(dispatch_get_main_queue(), ^{
// make some UI changes
// ...
// show actionSheet for example
});
}
Run Code Online (Sandbox Code Playgroud)
所以问题:
dispatch_async(dispatch_get_main_queue() 在主线程中调用是否安全且良好的解决方案?它会影响性能吗?[NSThread isMainThread]方法的主线程,并且dispatch_async仅在其他线程的情况下调用,但它将使我再创建一个方法或阻止这些UI更新.我有一个带有UIImageView子视图的UIView.我需要在UIImageView中加载图像而不阻止UI.阻塞呼叫似乎是:UIImage imageNamed:.以下是我认为解决这个问题的方法:
-(void)updateImageViewContent {
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage * img = [UIImage imageNamed:@"background.jpg"];
dispatch_sync(dispatch_get_main_queue(), ^{
[[self imageView] setImage:img];
});
});
}
Run Code Online (Sandbox Code Playgroud)
图像很小(150x100).
但是,加载图像时仍然会阻止UI.我错过了什么?
这是一个展示此行为的小代码示例:
基于UIImageView创建一个新类,将其用户交互设置为YES,在UIView中添加两个实例,并实现其touchesBegan方法,如下所示:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.tag == 1) {
self.backgroundColor= [UIColor redColor];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:[UIImage imageNamed:@"woodenTile.jpg"]];
});
[UIView animateWithDuration:0.25 animations:
^(){[self setFrame:CGRectInset(self.frame, 50, 50)];}];
}
}
Run Code Online (Sandbox Code Playgroud)
将标记1分配给其中一个imageView.
从加载图像的视图开始几乎同时点击两个视图时会发生什么?UI是否因为等待[self setImage:[UIImage imageNamed:@"woodenTile.jpg"]];返回而被阻止?如果是这样,我该如何异步执行此操作?
这是一个 带有ipmcc代码的github项目
使用长按然后拖动在黑色方块周围绘制一个矩形.据我理解他的答案,理论上白色选择矩形不应该在第一次加载图像时被阻挡,但实际上是.
项目中包含两个图像(一个小图片:woodenTile.jpg和一个较大图片:bois.jpg).结果与两者相同.
我真的不明白这与第一次加载图像时UI被阻止的问题有什么关系,但是PNG图像在不阻挡UI的情况下进行解码,而JPG图像会阻止UI.

UI的阻止从这里开始..

..并在此结束.

NSURL * url = …Run Code Online (Sandbox Code Playgroud) 我正在阅读教程:https: //www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1
并且遇到了QoS类用户交互的定义.它在那里提到它应该在主线程上运行.那么,我的问题是那之间的区别是什么
DispatchQueue.global(qos: .userInteractive).async{}
Run Code Online (Sandbox Code Playgroud)
和
DispatchQueue.main.async{}
Run Code Online (Sandbox Code Playgroud)
谢谢!!
好的,我喜欢Grand Central Dispatch并且在使用它之后相对成功,但这是我不完全理解的.
假设我已经创建了自己的串行队列
dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("myQueue", NULL);
Run Code Online (Sandbox Code Playgroud)
之后我这样做:
dispatch_async(myQueue, ^{
[self doStuff1];
});
// and a few lines later...
dispatch_sync(myQueue, ^{
[self doStuff2];
});
Run Code Online (Sandbox Code Playgroud)
第一个调度是异步的.那么,它将同时完成,对吧?如果myQueue是串行的怎么办?串行队列如何并行执行,或者如果不按顺序执行?
谢谢
我已经看到了一些相关问题,但似乎没有人回答这个问题.我想写一个在后台做一些工作的方法.我需要这个方法在用于原始方法调用的同一个线程/队列上调用完成回调.
- (void)someMethod:(void (^)(BOOL result))completionHandler {
dispatch_queue_t current_queue = // ???
// some setup code here
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL ok = // some result
// do some long running processing here
dispatch_async(current_queue, ^{
completionHandler(ok);
});
});
Run Code Online (Sandbox Code Playgroud)
这里需要什么神奇的咒语才能在与调用相同的队列或线程上调用完成处理程序sameMethod?我不想假设主线程.当然dispatch_get_current_queue不会被使用.
我想同时下载一些文件,例如100个文件.所以我决定将我的下载线程添加到调度队列,GCD将调整同时运行的线程数.
这里的问题是:块dispatch_async将立即完成,因为task将在另一个线程上运行.因此,如果urls长度为100,它将立即创建100个线程.
var queueDownloadTask = dispatch_queue_create("downloadQueue", nil)
for url in urls {
dispatch_async(queueDownloadTask) {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let fileTransferSession = NSURLSession(configuration: config)
let task = fileTransferSession.downloadTaskWithURL(url, completionHandler: { (responseUrl, response, error) -> Void in
println("completed")
})
task.resume()
}
}
Run Code Online (Sandbox Code Playgroud)
如何配置块dispatch_async以等待下载任务完成?我不想使用dispatch_semaphore,因为它只允许同时运行一个下载任务.
ios ×7
objective-c ×5
swift ×3
arrays ×1
async-await ×1
enumeration ×1
iphone ×1
nsthread ×1
qos ×1
queue ×1
uiimageview ×1