通常,如果您在NSOperationQueue上生成后台线程或运行NSOperation,则需要为该线程或操作创建NSAutoreleasePool,因为默认情况下不存在.
相同的规则是否适用于放置在Grand Central Dispatch队列中并将在非主线程上运行的块?也就是说,您是否需要在每个块中创建一个NSAutoreleasePool,并将其分派给主队列以外的任何其他块?
在我的有限测试中,我没有看到通常在后台线程或NSOperations中看到的自动释放对象的控制台警告.但是,我似乎无法找到关于此的明确文档,所以我想知道是否有人可以指出这里的陈述.
我需要同步在主队列上调度一个块.我不知道我目前是在主线程上运行还是不运行.天真的解决方案看起来像这样:
dispatch_sync(dispatch_get_main_queue(), block);
Run Code Online (Sandbox Code Playgroud)
但是如果我当前在主队列上运行的块中,则此调用会产生死锁.(同步调度等待块完成,但块甚至没有开始运行,因为我们正在等待当前块完成.)
显而易见的下一步是检查当前队列:
if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
Run Code Online (Sandbox Code Playgroud)
这有效,但很难看.在我至少将它隐藏在一些自定义功能之前,是不是有更好的解决方案来解决这个问题?我强调我不能异步调度块 - 应用程序处于异步调度块将"执行得太晚"的情况.
我遇到了一个场景,我有一个委托回调,可能发生在主线程或另一个线程上,我不知道哪个直到运行时(使用StoreKit.framework).
我还需要在该回调中更新UI代码,这需要在函数执行之前发生,因此我最初的想法是拥有这样的函数:
-(void) someDelegateCallback:(id) sender
{
dispatch_sync(dispatch_get_main_queue(), ^{
// ui update code here
});
// code here that depends upon the UI getting updated
}
Run Code Online (Sandbox Code Playgroud)
当它在后台线程上执行时,它工作得很好.但是,当在主线程上执行时,程序陷入僵局.
这本身似乎对我有意思,如果我读的文档dispatch_sync正确的,那么我希望它只是执行彻底,不担心它安排到runloop块,如说在这里:
作为优化,此函数在可能的情况下调用当前线程上的块.
但是,这不是太大的交易,它只是意味着更多的打字,这导致我采用这种方法:
-(void) someDelegateCallBack:(id) sender
{
dispatch_block_t onMain = ^{
// update UI code here
};
if (dispatch_get_current_queue() == dispatch_get_main_queue())
onMain();
else
dispatch_sync(dispatch_get_main_queue(), onMain);
}
Run Code Online (Sandbox Code Playgroud)
然而,这似乎有点倒退.这是制作GCD的一个错误,还是我在文档中遗漏了什么?
multithreading objective-c grand-central-dispatch objective-c-blocks
在其他一些方面,有以下两种方式来获取队列GCD:
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_get_main_queue();
Run Code Online (Sandbox Code Playgroud)
如果我没有完全错误,"主队列"正在主线程上执行,并且适用于执行UI工作的"回调"块.
这是否意味着"全局队列"是在后台线程上运行的?
我在修改线程内的视图时遇到问题.我试图添加一个子视图,但显示大约需要6秒或更长时间.我终于搞定了,但我不知道究竟是怎么回事.所以我想知道为什么它有效,以下方法之间有什么区别:
//this worked -added the view instantly
dispatch_async(dispatch_get_main_queue(), ^{
//some UI methods ej
[view addSubview: otherView];
}
//this took around 6 or more seconds to display
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView
waitUntilDone:NO];
//Also didnt work: NSNotification methods - took also around 6 seconds to display
//the observer was in the viewController I wanted to modify
//paired to a method to add a subview.
[[NSNotificationCenter defaultCenter] postNotificationName:
@"notification-identifier" object:object];
Run Code Online (Sandbox Code Playgroud)
作为参考,这是在ACAccountStore类的Completetion Handler中调用的.
accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
//my methods were …Run Code Online (Sandbox Code Playgroud) 在最长的时间里,我认为异步是在后台线程上运行某些东西的同义词,而同步意味着在主线程上(阻止UI更新和交互).我明白,不在主线程上运行昂贵的操作是因为它不允许在主线程被占用时发生UI操作,但为什么同步麻烦?
但是,我注意到你可以在主线程上进行异步调用,在后台线程上进行同步调用.
我总是听到人们说不要同步或在主线程上使用昂贵的调用,因为它会阻止用户的UI.这两个不同的问题我应该确保我不这样做吗?有什么区别?
multithreading asynchronous objective-c grand-central-dispatch ios
跟我说,这需要一些解释.我有一个看起来像下面的功能.
上下文:"aProject"是名为LPProject的核心数据实体,其名为"memberFiles"的数组包含另一个名为LPFile的Core Data实体的实例.每个LPFile表示磁盘上的文件,我们要做的是打开每个文件并解析其文本,查找指向OTHER文件的@import语句.如果我们找到@import语句,我们希望找到它们指向的文件,然后通过向代表第一个文件的核心数据实体添加关系,将该文件"链接"到该文件.由于所有这些都需要一些时间在大文件上,我们将使用GCD在主线程上完成.
- (void) establishImportLinksForFilesInProject:(LPProject *)aProject {
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (LPFile *fileToCheck in aProject.memberFiles) {
if (//Some condition is met) {
dispatch_async(taskQ, ^{
// Here, we do the scanning for @import statements.
// When we find a valid one, we put the whole path to the imported file into an array called 'verifiedImports'.
// go back to the main thread and update the model (Core Data is not thread-safe.)
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"Got to main thread.");
for …Run Code Online (Sandbox Code Playgroud) cocoa core-data objective-c grand-central-dispatch objective-c-blocks
如果我有一个串行队列,我怎么能从主线程告诉它立即停止执行并取消其所有任务?
好的,所以我在Xcode 8中发现了新的Swifty Dispatch API.我很开心使用DispatchQueue.main.async,我一直在浏览DispatchXcode中的模块以找到所有新的API.
但我也用它dispatch_once来确保像单例创建和一次性设置这样的事情不会被多次执行(即使在多线程环境中)......并且dispatch_once在新的Dispatch模块中找不到它?
static var token: dispatch_once_t = 0
func whatDoYouHear() {
print("All of this has happened before, and all of it will happen again.")
dispatch_once(&token) {
print("Except this part.")
}
}
Run Code Online (Sandbox Code Playgroud) objective-c ×7
ios ×6
iphone ×4
cocoa ×2
asynchronous ×1
cocoa-touch ×1
concurrency ×1
core-data ×1
libdispatch ×1
macos ×1
swift ×1
swift3 ×1
uikit ×1
xcode ×1