Apple’s UIKit is generally designed to be dealt with from within the main thread – operating with it from another thread can result in unpredictable results, including:
- Everything may be fine
- The user interface element may not be redrawn after your property changes
- UIKit will give you a warning in the console, and throw an exception
- The application will crash
- The application won’t crash, and the UI will be left in an undefined state
The question then becomes: how can we update our user interface from a background thread? Utilising Apple’s Grand Central Dispatch APIs is one such way.
Suppose one of your UIViewControllers receives a message to update the background color of its main view. This method is called from a background thread (say, when a particular network packet arrives). We can attach ourselves to the main thread, make the call, and then return to our background thread so we can continue to process other network packets.
- ( void )updateBackgroundColor:(UIColor *)color
{ dispatch_sync(dispatch_get_main_queue(), ^{
self .view.backgroundColor = color;
});
} |
Taking a closer look at this, we have:
dispatch_sync(dispatch_queue_t queue, ^( void )block)
|
The “sync” part of the function name (as differentiated from “async”) means that the code that comes after the dispatch_sync call (and in this case, the code which sent the -updateBackgroundColor: message) will not continue to run until the work inside the block is done. This can be useful where the code that follows makes the assumption that the work inside the block has been done (e.g. if it were then to query the backgroundColor property of the view later on). Making the “async” version of the call throws the work to be done on a queue, and processes it later on, when the specified queue gets its chance to run again. It looks similar to the synchronous version:
1
|
dispatch_async(dispatch_queue_t queue, ^( void )block)
|
Many of the dispatch_* functions operate on dispatch queues. Here, we are operating on the main queue, which is connected with the main run loop (our UI thread):
dispatch_get_main_queue() |
What about if we want to be able to call the same method, but from the UI thread? This creates a problem! The dispatch_sync function places its block of work to be done at the end of the main dispatch queue. It will then block until that work has been done. However, we’re already in the main thread, and until we return to the run loop, the block won’t be scheduled to run. This creates a deadlock – something we want to avoid. We can fix this with the following modification:
- ( void )updateBackgroundColor:(UIColor *)color
{ if ([ NSThread isMainThread])
{
self .view.backgroundColor = color;
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
self .view.backgroundColor = color;
});
}
} |
This is a little ugly, and duplicates the code – we can change it like this:
- ( void )updateBackgroundColor:(UIColor *)color
{ dispatch_block_t work_to_do = ^{
self .view.backgroundColor = color;
}
if ([ NSThread isMainThread])
{
work_to_do();
}
else
{
dispatch_sync(dispatch_get_main_queue(), work_to_do);
}
} |
Even better, we can throw this into a function which can be used elsewhere:
void RUN_ON_UI_THREAD(dispatch_block_t block)
{ if ([ NSThread isMainThread])
block();
else
dispatch_sync(dispatch_get_main_queue(), block);
} |
so that our code is simplified to:
- ( void )updateBackgroundColor:(UIColor *)color
{ RUN_ON_UI_THREAD(^{
self .view.backgroundColor = color;
});
} |
相关推荐
Updating Your Form from Another Thread without Creating Delegates for Every Type of Update
NULL 博文链接:https://wangtuoy.iteye.com/blog/662380
edition of the Single UNIX Specification, folding in the changes from two sets of corrigenda. In 2008, The Open Group created a new version of the Single UNIX Specification, updating the base ...
Title: The Gourmet iOS Developer’s Cookbook: Even More Recipes for Better iOS App Development Author: Erica Sadun Length: 304 pages Edition: 1 Language: English Publisher: Addison-Wesley Professional...
RayWenderlich 最新...Discover the new features for developers in iOS 11, such as ARKit, Core ML, Vision, drag & drop, document browsing, the new cha nges in Xcode 9 and Swift 4 — and much, much more.
BHT_BASIC40_Updating_from_BHT_BASIC36.pdfBHT_BASIC40_Updating_from_BHT_BASIC36.pdf
This book leads you through the essential concepts and new iOS 10 SDK and Swift 3 programming language APIs to build iPhone and iPad database driven applications using the defacto standard for data ...
[2] , ranging from web servers to games, programming languages and most of the application types that are in use on modern computers. Ports will be discussed further in the section The Ports ...
Displaying inventory items in the UI 186 ■ Equipping a key to use on locked doors 188 ■ Restoring the player’s health by consuming health packs 190 8.5 Summary 191 STRONG FINISH ......................
The data is stored in one place and the index is stored in another. Pointers indicate the storage location of the indexed items in the underlying table. In a nonclustered index, the leaf level ...
Virtualization and cloud make it easy to rapidly expand the size of infrastructure, but the habits and practices we used in the past with hardware-based infrastructure don't keep up. Teams end up with...
Fuzzy Strategy Updating in the Prisoner’s Dilemma Game
The examples use time-tested code from working applications. What You'll Learn: How to create database and database applications using iOS and Swift How to insert, select, edit, and delete records ...
Combating Spyware in the Enterprise is the first book published on defending enterprise networks from increasingly sophisticated and malicious spyware. Combating Spyware in the Enterprise begins by ...
基于Kriging模型的复杂结构有限元模型修正,刘洋,唐旭,对于大型、复杂结构的模型修正问题,由于结构本身的动力分析往往要消耗大量的计算时间、占用大量的存储空间,所以常规的迭代计算
Virtualization and cloud make it easy to rapidly expand the size of infrastructure, but the habits and practices we used in the past with hardware-based infrastructure don't keep up. Teams end up with...
from your web sites—even the default installation shown in Figure 1-1 shows how pleasing a Joomla web site can look. Adding content or updating the design of your entire web site is a snap . . . and ...
The first edition of this book was released in 2001 at the same time Microsoft released the Beta 2 build of .NET 1.0. Working on that first edition was certainly a challenge, given that the APIs and ...
- Enhanced the mechanism to report memory hardware errors in the Memory torture test. Release 5.3 build 1033 WIN32 release 1 October 2008 - Changes to correct a BurnInTest crash problem on some ...
-完全可定制的UI -无需服务器端代码:普通的HTTP服务器就足够了 -顺序和非顺序补丁处理 -更新的最短路径计算 -通过完全修复触发检测非常老的版本 -自我更新功能 管理工具 -版本管理 -补丁管理 -启动更新管理 - CI /...