iOS零散知识

应用沙盒

  • 应用程序包:保存所有资源文件和可执行文件
  • Documents:需要持久化的数据,iTunes会同步。eg:游戏存档
  • tmp:临时数据,应用不运行时系统也可能清除该目录下文件,iTunes不会同步
  • Library/Cache:需要持久化的文件,iTunes不会同步。一般存储体积大、不需要备份的非重要数据
  • Library/Preference:保存应用的偏好设置,iOS的settings应用会在该目录中查找应用的设置信息,iTunes会同步

数据存储

1.XML属性列表(Plist)

  • 存储字典和数组,不能存储自定义对象
  • 判断一个对象能不能使用plist就看有没有writeToFile方法

2.Preference(偏好设置)

  • 好处
    • 不需关心文件名
    • 快速的做键值对存储
  • 底层就是封装了一个字典
//存
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    
    [userDefaults setObject:@"xmg" forKey:@"account"];
    [userDefaults setObject:@"123" forKey:@"pwd"];
    [userDefaults setBool:YES forKey:@"rmbPwd"];
    // 在iOS7之前,默认不会马上把跟硬盘同步
    // 同步
    [userDefaults synchronize];
    
//取
NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"pwd"];

3.NSKeyedArchiver归档(NSCoding) / NSKeyedUnarchiver解档

3.1Person

#import <Foundation/Foundation.h>

// 如果一个自定义对象想要归档,必须遵守NSCoding协议,实现协议方法。
@interface Person : NSObject <NSCoding>
@property (nonatomic, assign) int age;
@property (nonatomic, strong) NSString* name;
@end
#import "Person.h"

@implementation Person

// 什么时候调用:自定义对象归档的时候
// 作用:用来描述当前对象里面的哪些属性需要归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    // name
    [aCoder encodeObject:_name forKey:@"name"];
    
    // age
    [aCoder encodeInt:_age forKey:@"age"];
    
}

// 什么时候调用:解档对象的时候调用
// 作用:用来描述当前对象里面的哪些属性需要解档
// initWithCoder:就是用来解析文件的。
- (id)initWithCoder:(NSCoder *)aDecoder
{
    // super:NSObject
    if (self = [super init]) {
        
        // 注意:一定要给成员变量赋值
        // name
       _name = [aDecoder decodeObjectForKey:@"name"];
        
        // age
       _age = [aDecoder decodeIntForKey:@"age"];

    }
    return self;
}
@end

//存
Person *p = [[Person alloc] init];
    p.age = 18;
    
    // 获取cache
    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    
    // 获取文件的全路径
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"person.data"];
    
    // 把自定义对象归档
    [NSKeyedArchiver archiveRootObject:p toFile:filePath];

//取
// 获取cache
    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    
    // 获取文件的全路径
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"person.data"];
    
    // 解档
    Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    
    NSLog(@"%d",p.age);

3.2RedView

#import "RedView.h"

@implementation RedView

// 解析文件都会调用这个方法
// 因为Xib和Storyboard也属于文件,所以通过Xib和Storyboard加载控件时会调用initWithCoder方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
    // 只要父类遵守了NSCoding,就调用initWithCoder
    // 先初始化父类
    if (self = [super initWithCoder:aDecoder]) {
        NSLog(@"%s",__func__);
    }
    return self;
}


// 通过代码初始化的时候,调用init方法,底层就会调用initWithFrame
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        NSLog(@"%s",__func__);
    }
    return self;
}
@end

4.FMDB


JSON(NSJSONSerialization)

1.JSON -> NSData

[NSJSONSerialization JSONObjectWithData:
 options: 
 error:];

options:

//返回可变容器,NSMutableDictionary或NSMutableArray
NSJSONReadingMutableContainers

//返回的JSON对象中字符串的值为NSMutableString
NSJSONReadingMutableLeaves

//允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment。例如使用这个选项可以解析 @“123” 这样的字符串
NSJSONReadingAllowFragments

2.NSData -> JSON

[NSJSONSerialization dataWithJSONObject:
 options: 
 error:];
 
 options:
 NSJSONWritingPrettyPrinted

XML(NSXMLParser)

  • 全称是Extensible Markup Language,译作“可扩展标记语言”
  • 跟JSON一样,也是常用的一种用于交互的数据格式
  • 一般也叫XML文档(XML Document)
  • 一个常见的XML文档一般由以下部分组成
    • 文档声明
    • 元素(Element)
    • 属性(Attribute)
  • XML解析方式的选择建议
    • 大文件:NSXMLParser、libxml2(SAX:从根元素开始,按顺序一个元素一个元素往下解析)
    • 小文件:GDataXML、NSXMLParser、libxml2(DOM:一次性将整个XML文档加载进内存)
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:
[NSURLRequest requestWithURL:
[NSURL URLWithString:
@"http://120.25.226.186:32812/video?type=XML"]] 
completionHandler:
^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        parser.delegate  = self;
        [parser parse];
       
    }];
    
[task resume];
    
     
#pragma mark - <NSXMLParserDelegate>
//开始解析XML文档
- (void)parserDidStartDocument:(NSXMLParser *)parser

//解析完毕
- (void)parserDidEndDocument:(NSXMLParser *)parser

//解析到某个元素的开头(比如解析<videos>)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict

//解析到某个元素的结尾(比如解析</videos>)
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName


网络--数据上传

//创建url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
    
//创建请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

request.HTTPMethod = @"POST";

//设置请求对象的请求头(告诉服务器这是一个上传请求)
[request setValue:@"multipart/form-data; boundary=himyfairy88888" forHTTPHeaderField:@"Content-Type"];
    
//设置请求体
NSMutableData *data = [NSMutableData data];

//分割线
[data appendData:[@"--" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"himyfairy88888" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//文件参数名
[data appendData:[@"Content-Disposition: form-data; name=\"ql\"; filename=\"emoji-mosaic.jpg\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//文件的类型
[data appendData:[@"Content-Type: image/jpeg" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//文件数据
[data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

[data appendData:[NSData dataWithContentsOfFile:@"/Users/Neo/Desktop/emoji-mosaic.jpg"]];

[data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//结束标记
[data appendData:[@"--" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"himyfairy88888" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"--" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

request.HTTPBody = data;

[[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
   
   NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
   
}] resume];

NSLog(@"upload执行完毕");

NSURLSession

1.get

// 获得NSURLSession对象
NSURLSession *session = [NSURLSession sharedSession];

// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=4324"]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];

// 启动任务
[task resume];

2.get简略

// 获得NSURLSession对象
NSURLSession *session = [NSURLSession sharedSession];

// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=4324"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];

// 启动任务
[task resume];

3.post

// 获得NSURLSession对象
NSURLSession *session = [NSURLSession sharedSession];

// 创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/login"]];
// 请求方法
request.HTTPMethod = @"POST"; 
// 请求体
request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding]; 

// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];

// 启动任务
[task resume];

4.download

// 获得NSURLSession对象
NSURLSession *session = [NSURLSession sharedSession];

// 获得下载任务
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
    
// 文件将来存放的真实路径(默认是放在tmp文件夹内)
NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];

// 剪切location的临时文件到真实路径
NSFileManager *mgr = [NSFileManager defaultManager];
[mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];
}];

// 启动任务
[task resume];

5.NSURLSessionDataDelegate

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

// 获得NSURLSession对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];

// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=4324"]]];

// 启动任务
[task resume];
}

#pragma mark - <NSURLSessionDataDelegate>
/**
 * 1.接收到服务器的响应
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    // 允许处理服务器的响应,才会继续接收服务器返回的数据
    completionHandler(NSURLSessionResponseAllow);
    
    // void (^)(NSURLSessionResponseDisposition)
}

/**
 * 2.接收到服务器的数据(可能会被调用多次)
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{

}

/**
 * 3.请求成功或者失败(如果失败,error有值)
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{

}

6.大文件下载

#import "ViewController.h"
@interface ViewController () <NSURLSessionDownloadDelegate>
/** 下载任务 */
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
@end

@implementation ViewController
//开始下载
- (IBAction)start:(id)sender {
    // 获得NSURLSession对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
    // 获得下载任务
    self.task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]];
    
    // 启动任务
    [self.task resume];
}

//暂停下载
- (IBAction)pause:(id)sender {
    [self.task suspend];
}

//继续下载
- (IBAction)goOn:(id)sender {
    [self.task resume];
}

#pragma mark - <NSURLSessionDownloadDelegate>
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"didCompleteWithError");
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
    NSLog(@"didResumeAtOffset");
}

/**
 * 每当写入数据到临时文件时,就会调用一次这个方法
 * totalBytesExpectedToWrite:总大小
 * totalBytesWritten: 已经写入的大小
 * bytesWritten: 这次写入多少
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSLog(@"--------%f", 1.0 * totalBytesWritten / totalBytesExpectedToWrite);
}

//下载完毕就会调用一次这个方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    // 文件将来存放的真实路径
    NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    
    // 剪切location的临时文件到真实路径
    NSFileManager *mgr = [NSFileManager defaultManager];
    [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];
}
@end


NSStirng和NSDate转换

  • NSDate -> NSStirng
- (NSString *)stringFromDate:(NSDate *)date
{
    //设置Date格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    //转换为NSString
    NSString *dateStr = [formatter stringFromDate:date];
    return dateStr;
}
  • NSStirng -> NSDate
- (NSDate *)dateFromString:(NSString *)string
{
    //设置Date格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    //转换为NSDate
    NSDate *date = [formatter dateFromString:string];
    return date;
}


Appearance

  • 通过appearance统一设置所有UITabBarItem的文字属性,后面带有UI_APPEARANCE_SELECTOR的方法, 都可以通过appearance对象来统一设置
[[UITabBarItem appearance] setTitleTextAttributes:@{
                                                        NSForegroundColorAttributeName : [UIColor colorWithRed:39 / 255.0 green:151 / 255.0 blue:217 / 255.0 alpha:1.0]
                                                        } forState:UIControlStateSelected];
设置前

设置后

tableViewCellSelection

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

推荐阅读更多精彩内容