The advantages and disadvantages
1. Advantages: NSThread is more lightweight than the other two multithreading schemes and controls thread object 2 more intuitively. Disadvantages: need to manage their own thread life cycle, thread synchronization. Locking data for thread synchronization has some system overhead
Thread creation
// 1. Initialize the thread
// Selector: a method executed by a thread that takes at most one argument
// target: selector to which the message is sent
Argument: the unique argument passed to selector, which can also be nil
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
// 2. Create and start a new thread
- (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
// 3. Implicitly create and start threads
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg;
// get the main thread
+ (NSThread *)mainThread;
// 5. Get the current thread
+ (NSThread *)currentThread;
Copy the code
Thread state
Thread state changes refer to multithreading (I) processes and threads.
// Start the thread
// The thread enters the ready state -> running state. The thread enters the dead state automatically when the task is completed
- (void)start;
// block (pause) the thread method
// The thread is blocked
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// Force the thread to stop
// The thread enters the dead state
+ (void)exit;
Copy the code
// 暂停2s
[NSThread sleepForTimeInterval:2];
/ / or
NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:date];
Copy the code
Other methods
// Determine whether the thread is the master thread (object method)
- (BOOL)isMainThread;
// Determine whether the thread is the primary thread (class method)
+ (BOOL)isMainThread;
// Thread name -- setter method
- (void)setName:(NSString *)n;
// Set thread priority (0.0-1.0, 1.0 superlative)
- (void)setThreadPriority:(double)p;
Copy the code
Communication between threads
// 1. Perform operations on the main thread
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;
// equivalent to the first method with kCFRunLoopCommonModes
// 2. Execute the operation on the specified thread
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5.2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5.2_0);
// 3. Perform the operation on the current thread, calling NSObject's performSelector: related method
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
Copy the code
Here is an example of downloading an image:
- Download images in the child thread;
- After downloading the image, call back to the main thread to refresh the view.
/** * Create a thread to download the image */
- (void)downloadImageOnSubThread {
// Call downloadImage in the created child thread to download the image
[NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil];
}
/** * Download the image and go back to the main thread to refresh the UI */
- (void)downloadImage {
NSLog(@"current thread -- %@"[NSThread currentThread]);
// 1. Get imageUrl
NSURL *imageUrl = [NSURL URLWithString:@"https://wiki-1259056568.cos.ap-shanghai.myqcloud.com/ios/20190627101912.png"];
// 2. Read data from imageUrl (download image) -- time consuming operation
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
// Create an image from binary data
UIImage *image = [UIImage imageWithData:imageData];
// 3. Go back to the main thread for image assignment and interface refresh
[self performSelectorOnMainThread:@selector(refreshOnMainThread:) withObject:image waitUntilDone:YES];
}
/** * return to main thread for image assignment and interface refresh */
- (void)refreshOnMainThread:(UIImage *)image {
NSLog(@"current thread -- %@"[NSThread currentThread]);
// Assign the image to imageView
self.imageView.image = image;
}
Copy the code
NSThread subclass
You can subclass NSThread and override the [the main] (https://developer.apple.com/documentation/foundation/nsthread/1418421-main) method to implement your thread ‘s main entry point. If you override [main](https://developer.apple.com/documentation/foundation/nsthread/1418421-main), you do not need to invoke the inherited behavior by calling super.
reference
link
- NSThread Reference