iOS开发之多线程(1)—— 概述 iOS开发之多线程(2)—— Thread iOS开发之多线程(3)—— GCD iOS开发之多线程(4)—— Operation iOS开发之多线程(5)—— Pthreads iOS开发之多线程(6)—— 线程安全与各种锁
Xcode 11.5 Swift 5.2.2
一个Thread即为一个线程.
OC中的属性方法(Swift方法名类似):
#pragma mark - 属性 // 可以使用返回的字典来保存线程的特定数据. (这只是一个普通的字典, 用来保存所有开发者感兴趣的数据.) @property (readonly, retain) NSMutableDictionary *threadDictionary; // 线程优先级 @property double threadPriority API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); // To be deprecated; use qualityOfService below // 线程优先级 (枚举常量) @property NSQualityOfService qualityOfService API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); // read-only after the thread is started // 保存的线程名字 (不明觉厉) @property (nullable, copy) NSString *name API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 线程的堆内存大小字节数 (必须是4KB的倍数, 要使设置有用, 必须在start方法调用前设置.) @property NSUInteger stackSize API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 是否主线程 @property (readonly) BOOL isMainThread API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 线程是否在执行 @property (readonly, getter=isExecuting) BOOL executing API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 线程是否已经结束 @property (readonly, getter=isFinished) BOOL finished API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 线程是否已经调用cancel方法 (调用cancel后线程不会立即退出, 此时finished有可能为NO) @property (readonly, getter=isCancelled) BOOL cancelled API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); #pragma mark - 类方法 // 当前线程 (类方法) @property (class, readonly, strong) NSThread *currentThread; // 是否主线程 (类方法) @property (class, readonly) BOOL isMainThread API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // reports whether current thread is main // 获取主线程 (类方法) @property (class, readonly, strong) NSThread *mainThread API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 是否多线程 (如果是通过非Cocoa的api开启的线程, 比如POSIX或者Multiprocessing Services APIs, 被认为不是多线程.) + (BOOL)isMultiThreaded; // 线程休眠到aDate的时候 (在休眠期间run loop不处理事件) + (void)sleepUntilDate:(NSDate *)date; // 休眠ti秒 + (void)sleepForTimeInterval:(NSTimeInterval)ti; // 强行停止线程 (应该避免调用此方法, 因为它不会使线程有机会清理在执行过程中分配的任何资源.) + (void)exit; // 获取线程优先级 (0.0~1.0) (典型值是0.5, 但是由于优先级是由内核确定的, 因此不能保证此值实际上是多少) + (double)threadPriority; // 设置线程优先级 + (BOOL)setThreadPriority:(double)p; #pragma mark - 对象方法 // 给线程发送取消信号, 最终何时取消由线程本身决定 - (void)cancel API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 开启线程 - (void)start API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 执行start方法后会自动调用main方法 (如果要继承NSThread, 可以重写main方法来执行新线程的主要部分) - (void)main API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // thread body method #pragma mark - 创建 // 创建新线程 (iOS 10+可用) + (void)detachNewThreadWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // 创建新线程 (使用指定的选择器作为线程入口点) + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument; // 初始化NSThread对象 - (instancetype)init API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) NS_DESIGNATED_INITIALIZER; // 初始化NSThread对象 (使用selector) - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 初始化NSThread对象 (使用block, iOS 10+可用) - (instancetype)initWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); #pragma mark - 线程切换 // 切换到主线程 (在主线程调用SEL方法), wait: 是否阻塞当前线程 - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array; // 同上 (线程模式为kCFRunLoopCommonModes) - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait; // 切换到指定线程 (在指定线程调用SEL方法) - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 同上 (线程模式为kCFRunLoopCommonModes) - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 在新的后台线程上调用SEL方法 (注意: 此方法创建新线程) - (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));创建一个子线程, 在子线程中改变value值, 然后回到主线程打印该value值.
OC
- (void)viewDidLoad { [super viewDidLoad]; [NSThread detachNewThreadSelector:@selector(changeValue) toTarget:self withObject:nil]; } - (void)changeValue { NSLog(@"%s thread:%@, value=%d", __func__, [NSThread currentThread], self.value); self.value = 10; // 调用主线程 [self performSelectorOnMainThread:@selector(logValue) withObject:nil waitUntilDone:NO]; } - (void)logValue { NSLog(@"%s thread:%@, value=%d", __func__, [NSThread currentThread], self.value); } ----------------------------------------------------------------------------------------------------- log: -[ViewController changeValue] thread:<NSThread: 0x60000262b1c0>{number = 7, name = (null)}, value=0 -[ViewController logValue] thread:<NSThread: 0x60000266d0c0>{number = 1, name = main}, value=10Swift
class KKThread: NSObject { var value: Int = 0 @objc func startThread() { Thread.detachNewThreadSelector(#selector(changeValue), toTarget: self, with: nil) } @objc func changeValue() { print("\(#function), thread:\(Thread.current), value=\(self.value)") self.value = 5 // 调用主线程 self.performSelector(onMainThread: #selector(logValue), with: nil, waitUntilDone: false) } @objc func logValue() { print("\(#function), thread:\(Thread.current), value=\(self.value)") } }注: 关于OC中调用Swift请移步iOS开发之Swift篇(15)—— Swift与Objective-C混编
demo https://github.com/LittleLittleKang/KKThreadsDemo