Each IOS application has a main thread that is designed to update the UI interface and handle the user's touch events, so it is not possible to put other too-time-consuming operations on the main thread, or it will cause the main thread to clog (the phenomenon of card-machine), resulting in a very bad user experience. The general solution is to put those time-consuming operations into another thread to execute, multithreaded programming is the best way to prevent the main thread from clogging and increase operational efficiency:
1.iOS supports multiple levels of multi-threaded programming, the higher the level of abstraction, the more convenient to use, but also Apple's most recommended method.
2.NSThread: The three methods Apple offers are relatively lightweight, but need to manage the lifecycle, synchronization, and locking of threads, which can lead to some performance overhead.
Initialization of 1.NSThread
1. Initialize:
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
Parameter resolution:
- Selector: Thread execution method, this selector can only receive one parameter at most
- Target:selector object sent by message
- Argument: The only parameter passed to selector, or nil
A concise initialization method:
- Pros: Automatically start a thread after creating a thread
- Cons: Unable to set the thread in more detail
+ (void)detachNewThreadSelector:(SEL)selectortoTarget:(id)targetwithObject:(id)argument
[selfperformSelectorInBackground:@selectorwithObject:nil];
2. Thread Start-up
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];// 线程一启动,就会在线程thread中执行self的run方法[thread start];
3. Other basic usage
//主线程相关用法+ (NSThread// 获得主线程- (BOOL// 是否为主线程+ (BOOL// 是否为主线程//获得当前线程NSThread *current = [NSThread currentThread];//线程的名字- (void)setName:(NSString *)n;- (NSString *)name;
4. Status of the thread
To start a thread:
// 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态- (void
Blocking (pausing) threads
// 进入阻塞状态+ (void)sleepUntilDate:(NSDate *)date;+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
Force Stop Thread
// 进入死亡状态+ (void)exit;
注意:一旦线程停止(死亡)了,就不能再次开启任务
5. Multi-threaded security risks
Resource sharing:
- 1 blocks of resources may be shared by multiple threads, i.e.
多个线程可能会访问同一块资源
- For example, multiple threads access the same object, the same variable, the same file
- Problems can easily arise when multiple threads access the same piece of resources
数据错乱和数据安全
We can find that because of the multithreading reason, the money has become less, only 500.
Security Risk Analysis:
Multiple threads operate a resource at the same time, causing a resource update error, which should have been 19, and the result is 18.
WORKAROUND: Mutual exclusion lock
Mutexes are easy to understand when a thread accesses a resource and prohibits other threads from accessing the resource until the resource is released.
Mutex use format
@synchronized (Lock Object) {//code to be locked}
Note: Locking 1 parts of code with only 1 locks, with multiple locks is not valid
#Import "ViewController.h"@interfaceViewcontroller ()/** Conductor 1 * *@property(Nonatomic, Strong) Nsthread *thread1;/** Conductor 2 * *@property(Nonatomic, Strong) Nsthread *thread2;/** Conductor 3 * *@property(Nonatomic, Strong) Nsthread *thread3;/** Number of remaining votes * /@property(Nonatomic, assign) Nsinteger count;@end@implementationviewcontroller-(void) Viewdidload {[SuperViewdidload];//0. Initial number of votes leftSelf.count = -;//1. Creation of 3 conductorsNsthread *thread1 = [[Nsthread alloc]initwithtarget:self selector:@selector(Sell)Object: nil]; Thread1.name = @"A"; Self.thread1 = Thread1; Nsthread *thread2 = [[Nsthread alloc]initwithtarget:self selector:@selector(Sell)Object: nil]; Thread2.name = @"B"; Self.thread2 = thread2; Nsthread *thread3 = [[Nsthread alloc]initwithtarget:self selector:@selector(Sell)Object: nil]; Thread3.name = @"C"; Self.thread3 = thread3;} -(void) Touchesbegan: (Nsset *) touches withevent: (uievent *) event{//1. Let 3 conductors start selling tickets at the same time[Self.thread3 start]; [Self.thread2 start]; [Self.thread1 start];}/****************************************************************************************** just be @ Synchronized {} wrapped code, the same moment can only be executed by one thread Note: 1. As long as the shackles will consume 2 performance. The lock must pass an object as a lock 3. If you want to really lock the code, then multiple threads must use the same lock to line 4. When locking, reduce the range as much as possible, because the larger the range, the lower the performance is 5. @synchronized (self.obj)//Lock 6. In development, if you want to lock, the general situation is to use self**************************************************************************************** **/-(void) sell{ while(true) {@synchronized(self) {if(Self.count >0) {NSLog (@"Count:%ld Conductor:%@", Self.count,[nsthread Currentthread].name); Self.count--; }Else{NSLog (@"Sold Out"); [Nsthread exit]; } } }}@end
Advantages and disadvantages of mutual exclusion lock
Advantages: It can effectively prevent the data security problem caused by multi-thread snatch resource
Cons: Consumes a lot of CPU resources
Use of mutexes: Multiple threads rob the same piece of resources
Related Professional terminology: Thread synchronization
Thread synchronization means that multiple threads are executing on the same line (performing tasks sequentially)
Mutex is the use of thread synchronization technology
6. Atomic and non-atomic properties
1.OC has nonatomic and atomic two choices when defining attributes
- Atomic: Atomic attribute, locking for setter method (default is Atomic)
- Nonatomic: Non-atomic attribute, does not lock the setter method
2.nonatomic and atomic Contrast
- Atomic: Thread-safe, requires a lot of resources
- Nonatomic: Non-thread-safe, suitable for small memory mobile devices
Recommendations for 3.iOS Development
- All properties are declared as Nonatomic
- Try to avoid multiple threads robbing the same piece of resources
- As far as possible to locking, resource-grabbing business logic to the server-side processing, reduce the pressure of mobile clients
Note: The atomic system automatically adds a lock to us that is not a mutex/spin lock
Mutual exclusion and spin lock commonalities:
都能够保证多线程在同一时候, 只能有一个线程操作锁定的代码
Mutex and spin lock differences:
- If it is a mutex, if it is locked now, then the thread in the back will go to "hibernate" state until it is unlocked and the thread continues to execute.
- If it is a spin lock, if it is locked now, then the thread will not enter the dormant state, will always be silly wait, until after unlocking immediately execute
- Spin lock is more suitable for short operation
7. Inter-thread communication
1. What is called inter-thread communication
- In 1 processes, threads often do not exist in isolation and require frequent communication between multiple threads
2. The embodiment of inter-thread communication:
- 1 Threads pass data to another 1 threads
- After performing a specific task in 1 threads, go to another 1 thread to continue the task
3. Common methods for inter-thread communication:
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
- First parameter: Aselector represents the method of the created thread
- Second parameter: THR represents the incoming thread
- The third parameter: ARG represents the parameters of the method passed in to the thread
- The fourth parameter: the meaning of a waituntildone:
- If yes is passed in, the code for the following lines will not continue until the method in the main thread finishes executing
- If no is passed in, then you can continue to perform the lower of the following lines without waiting for the method in the main thread to finish executing
//表示跳转到主线程- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
4. Instance of thread communication:
Download the picture in the sub-thread, download the UI to update the main thread
1. Set Uiimageview constraints in storyboard
2. Write code
#import "ViewController.h" @interface viewcontroller ()@property(Weak,nonatomic)Iboutlet Uiimageview*imageview;@property(nonatomic,Strong)Nsthread*thread;@end @implementation viewcontroller - (void) Viewdidload {[SuperViewdidload];Nsthread*thread = [[NsthreadAlloc]initwithtarget: SelfSelector@selector(Downloadpic) object:Nil]; Thread. Name= @"Downloadimage"; Self. Thread= thread;} - (void) Touchesbegan: (Nsset *) touches withevent: (uievent *) event{[ Self. ThreadStart];} -(void) downloadpic{NSString*string = @"Http://avatar.csdn.net/7/4/5/1_misakahina.jpg";Nsurl*url = [NsurlUrlwithstring:string]; NSData *data = [NSData Datawithcontentsofurl:url];UIImage*image = [UIImageImagewithdata:data];//The Meaning of Waituntildone: //If incoming yes: the code for the other lines below will continue until the method in the main thread finishes executing //If the incoming is no: do not wait until the method in the main thread finishes executing, you can continue to execute the lower of the other rows below //[self performselectoronmainthread: @selector (showpicture:) withobject:image Waituntildone:yes]; //[self performselector: @selector (showpicture:) onthread:[nsthread Mainthread] Withobject:image waitUntilDone: YES];[ Self. ImageViewPerformselector:@selector(setimage:) onthread:[NsthreadMainthread] Withobject:image Waituntildone:YES];} - (void) Showpicture: (UIImage*) image{ Self. ImageView. Image= Image;}@end
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Multithreading---Nsthread