GeekBand-IOS进阶第三周笔记(多线程、数据持久化)
2016-09-25 本文已影响0人
周一见丶
多线程
NSThread
基本概念
多线程概念.png- 信号量:商场储物柜,一把钥匙一把锁;
- 互斥量:一个指纹锁的保险箱;
- 临界区:一段加密的代码,一次只能通过一个指令;
- 读写锁:只读不能写(拿到写锁定的权限才可以写);
- 条件变量:满足条件的指令都等着,到条件满足时一起执行。
多线程API
多线程API.png我们现在讨论的主要是NSThread,它是基于OC的接口。
两类线程.png
小区别:主进程退出时不管detached only执行完毕与否都立即结束,joinable by default没有执行完时主进程也不能退出。
Operation系列是对象,代表一个任务;Queue代表调度。
NSOperation+NSOperationQueue;Dispatch Queue更加灵活强大,基于C的。
Main Thread
主线程.pngNSThread.png
开销大的任务在新线程执行:
- NSThread类方法
+(void)detachNewThreadSelector:(SEL)toTarget:(id)withObject:(id)
- 自定义NSThread实例
此方法的作用一般是更新界面,只不过不能直接在view的加载过程更新,得间接调用这个方法来更新。
回主线程执行,任意一个NSObject对象(self)都可以调用此方法,BOOL值代表是否需要等待当前方法执行完毕才继续往下执行,一般是NO。
线程开销
线程开销.png线程属性及存储
线程属性及存储.png线程局部存储:存储在内存上,不和其他线程共享,没有并发访问冲突的问题。
线程控制
线程控制.png线程一般只有这三个状态,依次是执行、完成、取消。
- 一般线程最好是执行完再finished,这个调用此方法
[self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>]
- 停止线程:如果实在需要取消也用
-cancel
方法,不要用+exit
,因为cancel可以给你处理现场的机会,而exit比较粗暴,直接结束,什么都不管。 - sleep 睡眠,可以指定睡多少秒,也可以指定睡到什么时候。
- +currentThread 拿到当前线程的实例,以便于做start或cancel等操作。
NSRunLoop
基本概念
NSRunLoop.png- RunLoop总的来说就是管理线程的,它把查询事件的任务从线程里分离,在等待事件来之前,把线程设置为sleep,事件发生时唤醒它;
- 有两种接口:NSRunLoop和CFRunLoopRef。NSRunLoop如果有多个线程同时访问,不安全,CFRunLoopRef则没有这个限制;
- 得自己创建才有runLoop,主线程除外。
RunLoop Mode
RunLoop Mode.png- Mode可以说是一个集合,里面包含了输入事件源(如触摸事件、手势等)、Observer(可以添加代码,获取RunLoop的信息)、定时器;
- Source:custom source和source1。custom source包含一个回调可以理解为方法,custom source较为被动,source1比较主动。
- API:currentRunLoop,获取或者创建当前线程的runLoop;
currentMode,现在runLoop在哪个mode上;
limitDateForMode,让runLoop不要睡眠、不要在事件源等待转一圈立即返回,返回下一个Timer的时间,格式为NSDate,没有返回nil;
mainRunLoop,不管在哪儿,都可以拿出当前主线程的runLoop;
下面几个API顾名思义,不作解释了。
预定义RunLoop Mode
预定义RunLoop Mode.pngCommon Modes.png
NSRunLoop生命周期
NSRunLoop生命周期.png示例
示例API.pngNSoperation
多线程目的
线程目的.pngNSOperation抽象基类
NSOperation抽象基类.png子类
NSBlockOperation.pngNSInvocationOperation.png
依赖关系.png
NSOperation状态
NSOperation状态.pngGCD
queue.png自定义只能创建串行queue,为避免系统崩溃,只可以用默认的并行queue。
数据持久化
简单的一些方法
数据持久化.png- 简易存储方法
(void)easyload
{
//主程序目录
NSString *testpath = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"png"];
NSLog(@"testpath:%@",testpath);
//最后一个Documents目录
NSString *Documentspath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"Documents:%@",Documentspath);
//将图片存到Documents
NSString *imagepath = [Documentspath stringByAppendingPathComponent:@"imagetest.png"];
UIImage *imagetest = [UIImage imageNamed:@"test.png"];
NSData *imagedata = UIImagePNGRepresentation(imagetest);
[imagedata writeToFile:imagepath atomically:YES];
//将文本存到Documents
NSString *testpath01 = [Documentspath stringByAppendingPathComponent:@"test.txt"];
NSString *teststr = [NSString stringWithFormat:@"test"];
[teststr writeToFile:testpath01 atomically:YES encoding:NSUTF8StringEncoding error:nil];
//将数组存到Documents
NSString *arrayPath = [Documentspath stringByAppendingPathComponent:@"array.plist"];
NSArray *array = @[@"haha",@"121",@"nihao",@515];
[array writeToFile:arrayPath atomically:YES];
//将字典存到Documents
NSString *dictionarypath = [Documentspath stringByAppendingPathComponent:@"dictionary.plist"];
NSDictionary *dictionary = @{@"张三":@26,@"李四":@20};
[dictionary writeToFile:dictionarypath atomically:YES];
}
- NSUserDefaults
(void)writeNSUserDefaults
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"周一见" forKey:@"name"];
[userDefaults setBool:YES forKey:@"sex"];
[userDefaults setInteger:22 forKey:@"age"];
UIImage *image = [UIImage imageNamed:@"test.png"];
NSData *imageData = UIImagePNGRepresentation(image);
[userDefaults setObject:imageData forKey:@"image"];
[userDefaults synchronize];
}
(void)readNSUserDefaults
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *name = [userDefaults objectForKey:@"name"];
NSInteger age = [userDefaults integerForKey:@"age"];
NSData *imageData = [userDefaults dataForKey:@"image"];
UIImage *image = [UIImage imageWithData:imageData];
self.name.text = name;
self.age.text = [NSString stringWithFormat:@"%ld",age];
self.faceImage.image = image;
}