IOS基础理论知识复习(四)

   在简书看到大牛的知识点,发现很多知识点自己一知半解,能做项目但理论不够扎实,默默地去百度总结一下.放到这里和大家交流交流.

如有侵权,告知即删!

01.如何使用队列来避免资源抢夺?

后期跟新

02.数据持久化的几个方案

NSUserDefaults
plist(属性列表)
NSKeyedArchiver(对象归档)
iOS的嵌入式关系数据库SQLite3 (FMDB)
苹果公司提供的持久化工具 Core Data
上面几种方式,有一个共同的要素,就是应用的/Documents文件夹。每个应用都有自己的/Documents文件夹,且仅能读写各自/Documents文件中的内容
Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时备份该目录。例如,游戏应用可将游戏存档保存在该目录
tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录
Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据
Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用在该目录中查找应用的设置信息。iTunes同步设备时备份该目录

**NSUserDefaults:**
static NSString*constkey = @"key";
[[NSUserDefaults standardUserDefaults] setValue:@"YES"forKey: key];
[NSUserDefaults standardUserDefaults] valueForKey: key];
[userDefaults removeObjectForKey: key];
[userDefaults synchronize];

上面的示例代码基本就是NSUserDefaults所有用法了,虽然很简单,但还是有几点需要注意:
建议将所有的的key单独存放(好处自己领会)
NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。之前碰到个坑就是从服务器拿到数据部分用这种方式存储,服务器返回NSNull,我们这边也没有model层转,就直接存储了,导致app卡掉但并没有闪退之类,就是线程卡死的情况
同步问题,在适当的时候同步。因为synchronize的开销可能会很大,因为要比较内存中和存储中的所有用户偏好默认值,如果有好几百个key value 同步是非常消耗性能的。
偏好设置是专门用来保存应用程序的配置信息的,( 用过Settings.bundle的应该都很熟悉),所以一般不要在偏好设置中保存其他数据。
偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。

plist(属性列表)
首先需要知道什么是序列化对象(serialized object):指可以被转换为字节流以便于存储到文件中或通过网络进行传输的对象
可以被序列化的类型只有如下几种:
NSArray
NSMutableArray
NSDictionary
NSMutableDictionary
NSData
NSMutableData
NSString
NSMutableString
NSNumber
NSDate
还是直接上代码示例

/**
*  获取存储路径
*/- (NSString*)dataFilePath {
NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*documentDirectory = paths[0];
return[documentDirectory stringByAppendingPathComponent:@"data.plist"];
//nsstring真强大
}

我们在app处于非活跃状态时存储一些东东

UIApplication* app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(appWillResignActive:) name: UIApplicationWillResignActiveNotification object: app];
- (void)appWillResignActive:(NSNotification*)notification {
NSString* filePath = [self dataFilePath];
NSArray* arr = @[@1,@2,@3,@4];   
 [arr writeToFile: filePath atomically:YES];
}

在我们需要这些东东的时候从文件中读取

NSString* filePath = [self dataFilePath];
if([[NSFileManager defaultManager] fileExistsAtPath: filePath]) {
NSArray* arr = [[NSArray alloc] initWithContentsOfFile: filePath];
}

NSKeyedArchiver(对象归档):
在Cocoa中,Archiver是另一种形式的序列化,是任何对象都可实现的更常规的类型
说明:
只有遵守了NSCoding或 NSSecureCoding(更为安全的归档协议)协议,并且实现了协议里归档与解归档的方法的的类创建的对象才能够进行归档
最好也实现以下NSCopying,NSCopying与NSCoding一起实现好处在于允许复制对象,使用数据模型对象时有较大的灵活性
还是直接上代码

#import
@interface FourLines:NSObject
@property(copy, nonatomic)NSArray* lines;
@end
#import"FourLines.h"
//编解码的key 
static NSString *constklinesKey = @"klinesKey";
@implementationFourLines
#pragma mark -  NSCoding
- (void)encodeWithCoder:(NSCoder*)aCoder {   
[aCoder encodeObject: self.lines forKey: klinesKey];
}
- (nullable instancetype)initWithCoder:(NSCoder*)aDecoder {
self = [super init];
if(self) {
self.lines = [aDecoder decodeObjectForKey :klinesKey];   
}
returnself;
}
#pragma mark -  NSCopying
- (id)copyWithZone:(nullableNSZone*)zone {   
FourLines*copy= [[[self class] allocWithZone: zone] init];
NSMutableArray* linesCopy = [NSMutableArray array];
for(id line in self.lines) {       
[linesCopy addObject:[line copyWithZone: zone]];   
}
copy.lines= linesCopy;
return copy;
}
@end

写入数据,编码:文件路径还是用上面代码中定义的文件路径

- (void)appWillResignActive:(NSNotification*)notification {
NSString* filePath = [self dataFilePath];   
FourLines* lines = [[FourLines alloc]init];   
lines.lines= @[@"a",@"b",@"c",@"d"];
NSMutableData* data = [[NSMutableData alloc] init];
NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data];   
[archiver encodeObject: lines forKey: kRootKey];   
[archiver finishEncoding];   
[data writeToFile: filePath atomically:YES]; 
}

读取数据,解码:

NSString* filePath = [self dataFilePath];
if([[NSFileManager defaultManager] fileExistsAtPath: filePath]) {
NSData* data = [[NSMutableData alloc] initWithContentsOfFile: filePath];
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];        FourLines* four = [unarchiver decodeObjectForKey: kRootKey];       
[unarchiver finishDecoding];
for(int i =0; i <4; i++) {//to do}}
UIApplication* app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object: app];

<br />

03.说一下AppDelegate的几个方法?从后台到前台调用了哪些方法?第一次启动调用了哪些方法?从前台到后台调用了哪些方法?

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);

当应用程序启动时(不包括已在后台的情况下转到前台),调用此回调。launchOptions是启动参数,假如用户通过点击push通知启动的应用,这个参数里会存储一些push通知的信息。

– (void)applicationDidBecomeActive:(UIApplication *)application;
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

当应用程序全新启动,或者在后台转到前台,完全激活时,都会调用这个方法。如果应用程序是以前运行在后台,这时可以选择刷新用户界面。

– (void)applicationWillResignActive:(UIApplication *)application;
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

当应用从活动状态主动到非活动状态的应用程序时会调用这个方法。这可导致产生某些类型的临时中断(如传入电话呼叫或SMS消息)。或者当用户退出应用程 序,它开始过渡到的背景状态。使用此方法可以暂停正在进行的任务,禁用定时器,降低OpenGL ES的帧速率。游戏应该使用这种方法来暂停游戏。
调用时机可能有以下几种:锁屏,按HOME键,下接状态栏,双击HOME键弹出低栏,等情况。

– (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation NS_AVAILABLE_IOS(4_2);
// no equiv. notification. return NO if the application can’t open for some reason

当用户通过其它应用启动本应用时,会回调这个方法,url参数是其它应用调用openURL:方法时传过来的。
...............可以翻译官方文档自行查阅
<br />

04.NSCache优于NSDictionary的几点?

如果我们缓存使用得当,那么应用程序的响应速度就会提高。只有那种“重新计算起来很费事的数据,才值得放入缓存”,比如那些需要从网络获取或从磁盘读取的数据。
在构建缓存的时候很多人习惯用NSDictionary或者NSMutableDictionary,但是作者建议大家使用NSCache,它作为管理缓存的类,有很多特点要优于字典,因为它本来就是为了管理缓存而设计的。
NSCache优于NSDictionary的几点:
当系统资源将要耗尽时,NSCache具备自动删减缓冲的功能。并且还会先删减“最久未使用”的对象。
NSCache不拷贝键,而是保留键。因为并不是所有的键都遵从拷贝协议(字典的键是必须要支持拷贝协议的,有局限性)。
NSCache是线程安全的:不编写加锁代码的前提下,多个线程可以同时访问NSCache。
关于操控NSCache删减内容的时机
开发者可以通过两个尺度来调整这个时机:
缓存中的对象总数.
将对象加入缓存时,为其指定开销值。
对于开销值,只有在能很快计算出开销值的情况下,才应该考虑采用这个尺度,不然反而会加大系统的开销。
下面我们来看一下缓存的用法:缓存网络下载的数据

// Network fetcher class
typedef void(^EOCNetworkFetcherCompletionHandler)(NSData*data);
@interfaceEOCNetworkFetcher:NSObject
- (id)initWithURL:(NSURL*)url;
- (void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler;
@end// Class that uses the network fetcher and caches results
@interfaceEOCClass:NSObject
@end
@implementationEOCClass{NSCache*_cache;}
- (id)init {if((self= [superinit])) {    _cache = [NSCachenew];
// Cache a maximum of 100
URLs_cache.countLimit =100;
/**
* The size in bytes of data is used as the cost,
* so this sets a cost limit of 5MB.
*/
_cache.totalCostLimit = 5*1024*1024;   
}
return self;
}
- (void)downloadDataForURL:(NSURL*)url {
NSData*cachedData = [ _cache objectForKey: url];
if(cachedData) {
// Cache hit:存在缓存,读取
[self useData: cachedData];   
}else{
// Cache miss:没有缓存,下载
EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL: url];             
[fetcher startWithCompletionHandler:^(NSData*data){       
[ _cache setObject: data forKey: url cost: data.length];           
[self useData: data];       
}];   
}}
@end

在这里,我们使用URL作为缓存的key,将总对象数目设置为100,将开销值设置为5MB。
05.知不知道Designated Initializer?使用它的时候有什么需要注意的问题?


图中的Designated Initializer标志说明,系统推荐你使用initWithNibName: bundle:方法创建UIViewController及其子类,不要用其他什么乱七八糟的方法创建对象.
Designated Initializer表示指定初始化函数(唯一的初始化出口)。
如果需要创建新的指定初始化函数,则新的指定初始化函数在内部调用父类的指定初始化函数。而旧的指定初始化函数降级为便利初始化函数,你必须重写便利初始化函数,并在里面转调新的指定初始化函数。
如果需要自己创建便利初始化函数,则在里面必须转调指定初始化函数。(和第二点一样)
一个类可以拥有多个指定初始化函数。你需要根据初始化数据源选择其中一个指定初始化函数。(不建议为一种初始化数据源创建多个指定初始化函数)。
..........更加详细的可以直接百度:Designated Initializer

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,112评论 29 470
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,546评论 18 139
  • 目录 55. 命中注定 刚才那个令人尴尬的问题一过,整个办公室里的气氛顿时变轻松了,中间那个圆胖老头已经开始和亚洲...
    书咄咄阅读 286评论 1 3
  • 01 我参加了咪蒙举办的"新媒体大赛",然后落选了。 意料之中的事情。 无数怀揣着写作梦想的新媒体人都虎视眈眈的盯...
    菜菜小仙女阅读 428评论 0 0
  • 原文: 晋灵公不君。厚敛以彫墙。从台上弹人,而观其辟丸也。宰夫胹熊蹯不孰,杀之,寘诸畚,使妇人载以过朝。赵盾、士季...
    鸾英阅读 2,149评论 0 0