NSThread详解

属性

属性类型解释
currentThreadNSThread获取当前线程的一些信息
threadDictionaryNSMutableDictionary(readOnly)线程的一些本地属性,可以使用setObject:forkey:来配置
threadPrioritydouble(0.0~1.0)线程优先级,最高为1.0(已废弃,用qualityOfService)
qualityOfServiceNSQualityOfService枚举线程优先级
callStackReturnAddressesNSArray<NSNumber *>(readOnly),类属性返回在该线程中函数调用的地址的一个数组
callStackSymbolsNSArray<NSString *>(readOnly),类属性使用代码的方式获取调用栈
nameNSString线程名,主线程名为main
stackSizeNSUInteger线程使用的栈大小,默认512K,需要设置为4K的正整数倍,需要在start前设置,之后设置可以改变大小(表现为取值)但是不会影响栈区的真实页数
isMainThread(类属性,实例属性)BOOL(readOnly)是否是主线程
mainThread(类属性)NSThread(readOnly)获取主线程.
executingBOOL(readOnly)线程是否正在执行,执行前和执行完毕都会返回NO.
finishedBOOL(readOnly)线程是否完成
cancelledBOOL(readOnly)线程是否取消,只有调用了- (void)cancell才会取消,如果线程执行完毕再调用- (void)cancell也是会返回YES…

方法

// MAKR: 类方法

/// 创建一个线程并且执行.
+ (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;

/// 当前进程里面是否有多个子线程(一般来说.点击暂停看调用堆栈都是多个线程的,所以说个人觉得这个属性并没有什么卵用)
+ (BOOL)isMultiThreaded;

/// 当前线程睡眠date
+ (void)sleepUntilDate:(NSDate *)date;

/// 当前线程睡眠ti(秒)
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;

/// 退出当前线程
+ (void)exit;

/// 获取线程优先级
+ (double)threadPriority;

/// 设置线程优先级
+ (BOOL)setThreadPriority:(double)p;


// MARK: 实例方法

/// 下面这三个方法都需要调用`- (void)start`来开启线程
- (instancetype)init API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) NS_DESIGNATED_INITIALIZER;
- (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));
- (instancetype)initWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));


/// 取消线程
- (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));

/// 当子类化NSThread的时候可以通过重写该方法来改变入口
- (void)main API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));	// thread body method


其他有关的分类方法

/*
// @params:wait 一个布尔值,指定当前线程是否阻塞,直到在主线程上的接收器上执行指定的选择器之后。 指定YES以阻止此线程; 否则,指定NO以使此方法立即返回。
如果当前线程也是主线程,并且您传递YES,则立即执行消息,否则执行将排队等待下一次运行循环。
*/
/// 在主线程上执行方法...wait代表是等thread线程执行完毕才会执行下面的语句,否则异步执行.
@interface NSObject (NSThreadPerformAdditions)

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
	// equivalent to the first method with kCFRunLoopCommonModes

- (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));
- (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));
	// equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

@end


通知

/// 将要变成多线程的通知
FOUNDATION_EXPORT NSNotificationName const NSWillBecomeMultiThreadedNotification;
/// 已经变成单线程的通知
FOUNDATION_EXPORT NSNotificationName const NSDidBecomeSingleThreadedNotification;
/// 线程将要退出的通知
FOUNDATION_EXPORT NSNotificationName const NSThreadWillExitNotification;

枚举

typedef NS_ENUM(NSInteger, NSQualityOfService) {
    /// 与用户交互有关的.高优先级,需要立即响应.
    NSQualityOfServiceUserInteractive = 0x21,
    /// 由用户发起的需要立即得到结果的任务,优先级比NSQualityOfServiceUserInteractive低
    NSQualityOfServiceUserInitiated = 0x19,
    /// 不需要马上返回结果的任务,优先级比NSQualityOfServiceUserInitiated低
    NSQualityOfServiceUtility = 0x11,
    /// 后台任务,可能是在后台备份用户数据什么的,优先级比NSQualityOfServiceUtility低
    NSQualityOfServiceBackground = 0x09,
    /// 默认优先级.比NSQualityOfServiceUserInitiated低比NSQualityOfServiceUtility高.
    NSQualityOfServiceDefault = -1
} API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));

一些应用例子

当你启动应用的时候,需要XX秒才进入主屏

可千万别说这需求木有,我之前公司的老大就这么要求过.说是进入首页的速度太快了.得等个几秒钟再进去.(目的是让用户多看看启动图…这…)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
	```
	/// 线程休眠2秒(因为这里是主线程,所以就做到了延迟2秒进入主屏的需求...)
	[NSThread sleepForTimeInterval:2];
	```
	return YES;
}

也不是一定是准时的2秒,毕竟随着三方库的加入可能越来越大了.解决方案可以是1.把时间改短.2.异步加载三方库…

异步网络请求,主线程刷新UI

这个可能是最多的一种应用情况了.

- (void)viewDidLoad {
	dispatch_async...抱歉,走错片场了.
	NSThread *thread = [[NSThread alloc] initWithTarget:self selector:(requestNetWork:) object:params];
	[thread start];
}

/// params为请求参数
- (void)requestNetWork:(id)params {
	/// 假装request已经处理完毕了
	[self.session dataTaskWithRequest:request completionHandler:^ (NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) completionHandler {
		if (!error) {
			//请求成功.去主线程处理UI
			[self performSelectorOnMainThread:@selector(refreshUI:) withObject:arg waitUntilDone:NO];
		}
	}];
}

- (void)refreshUI:(id)arg {
	/// 主线程刷新UI
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值