一、什么是单例
1、一个单例,表示在一个应用的生命周期中,这个类的对象只能被实例化一次,也就是说一个类只能有一个对象。
2、单例的作用:因为,在一个应用中,一个类只有这一个单例对象,所以不管在A还是B还是。。。。中,只要实例化出来,都是同样的一个对象,所以我们可以通过这个对象来进行传值(举例:这个对象有N个属性,其中一个属性是等级,我们在A中给这个对象的等级属性赋值为X,那么不管到任何地方,只要实例化出来这个对象,他的等级属性的值就都是X,我们可以取出来使用)
注意:单例中的alloc无需手动内存释放,因为单例是全局范围内的对象,系统会在程序结束是自动释放,如果提前手动释放,会引起错误!!!
3、单例在AppDelegate.m文件中的写法
//非单例类
NormalClass *normalOne = [NormalClass alloc];//做一个对象
normalOne.name = @"lily";//为这个对象的name属性赋值为lily
NSLog(@"%@",normalOne.name);//用点语法取值
NormalClass *normalTwo = [NormalClass alloc];//做一个对象
NSLog(@"%@",normalTwo.name);//这次打印为空
//思考:
//通过下面的打印,可以看出这两个alloc出来的对象的地址是不同的
NSLog(@"%@",normalOne);
NSLog(@"%@",normalTwo);
//单例类(注意要用咱们自己写的单例方法)
SingleClass *singleOne = [SingleClass shareInstance];//用单例方法做一个对象
singleOne.name = @"lucy";
NSLog(@"%@",singleOne.name);
SingleClass *singleTwo = [SingleClass shareInstance];//用单例方法做一个对象
NSLog(@"%@",singleTwo.name);//可以成功打印出two的name属性的值
//我们并没有给singleTwo.name赋值,但是依然可以取出他的值,就是因为,我们使用了单例的方法,创建出来的singleOne和singleTwo其实是同一个对象(因为在单例方法中,alloc那块开辟空间的代码只被执行过一次)
//通过打印这两个对象的地址,来验证是不是同一个对象
NSLog(@"%@",singleOne);
NSLog(@"%@",singleTwo);
4、创建SingleClass单例类,.h文件的写法
#import <Foundation/Foundation.h>
//单例类
@interface SingleClass : NSObject
@property(nonatomic)NSString *name;
//下面是一个单例类的方法,未来这个类我们只通过下面的方法来开辟空间,实例化对象,以后单例不要用alloc来申请内存
+(SingleClass*)shareInstance;//未来我们看见shareInstance或者defaultXXXX等等就可以认为这是一个单例方法(约定俗成)
@end
5、创建SingleClass单例类,.m文件中单例写法的步骤
#import "SingleClass.h"
5.1、做一个静态全局指针变量
static SingleClass *single = nil;
@implementation SingleClass
+(SingleClass*)shareInstance
{
5.2、调用GCD(多线程的写法)的once方法来只做单例
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//大括号中的代码在整个应用中只会被执行一次
5.3、把上面的静态全局变量赋值,进行实例化
single = [SingleClass alloc];
});
5.4、把静态全局指针变量返回
return single;
}
@end
二、NSData操作方法
1、NSString与NSData之间的转换
NSString *str = @"abcdefg";
NSData *strData = [str dataUsingEncoding:NSUTF8StringEncoding];//把字符串变成data
NSLog(@"%@",strData);
NSString *backStr = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
NSLog(@"%@",backStr);
2、对象与NSKeyedArchiver之间的转换
2.1、数组与NSData之间的转换
NSArray *arr = @[@"aa",@"bb"];
NSData *arrData = [NSKeyedArchiver archivedDataWithRootObject:arr];//把对象变成data,一次只能把一个对象变成一个data
NSLog(@"%@",arrData);
NSArray *backArr = [NSKeyedUnarchiver unarchiveObjectWithData:arrData];//把data变成对象
NSLog(@"%@",backArr);
2.2、字典与NSData之间的转换
//请做一个字典,两个key:name:lily,age:18,用上面方法变成data
NSDictionary *a7 = [NSDictionary dictionaryWithObjectsAndKeys:@"lily",@"name",@"18",@"age", nil];
NSData *a8 = [NSKeyedArchiver archivedDataWithRootObject:a7];
NSDictionary *a9= [NSKeyedUnarchiver unarchiveObjectWithData:a8];
NSLog(@"%@",a9);
3、多个对象变成一个data的转换
#pragma mark 多个对象变成一个data(分割用的)
NSDictionary *dic = @{@"name":@"pp",@"age":@"16"};//成对出现,一对一个冒号,冒号前是key,后是value,多个对之间用,隔开
NSLog(@"%@",dic);
NSArray *secondArr = @[@"123",@"456"];
3.1、转换成Data的步骤
3.1.1、准备一个可变的NSData,当成容器来存我们的对象
NSMutableData *muData = [NSMutableData dataWithCapacity:0];
3.2.2、用alloc的方法做一个archiver的对象,初始化这个对象的时候,要用一个可变data,这个archiver将把很多个对象转成data,这些data都存在了这个可变data中
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:muData];
3.3.3、用archiver对象来调用encoding方法把对象存入这个可变data,同时给每一个存入的对象一个key,这个key就是未来我们从这个data中取得相应对象时候用的依据
[archiver encodeObject:dic forKey:@"ppp"];
[archiver encodeObject:secondArr forKey:@"qqqq"];
3.4.4、完成
[archiver finishEncoding];
NSLog(@"%@",muData);
3.2、Data转换成对象的步骤
#pragma mark 从data中根据之前设置好的key找到对应的对象
3.2.1、做一个NSKeyedUnArchiver对象,初始化的时候用一个data,这个data里存着很多个对象
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:muData];
3.2.2、通过一个key,用unArchiver找到对应的对象,调用decode方法
NSDictionary *unDic = [unArchiver decodeObjectForKey:@"ppp"];
NSLog(@"%@",unDic);
3.2.3、完成
[unArchiver finishDecoding];
三、文件操作
NSString *directory = NSHomeDirectory();//找到当前应用的沙盒
NSString *document = [directory stringByAppendingString:@"/Documents"];//找到沙盒中的Documents文件夹
1、文件外操作
1.1、文件管理器(实例化一个文件操作的工具对象)
NSFileManager *manager = [NSFileManager defaultManager];//其实是一个单例对象
//接下来的对文件的操作都是用这个manager进行的
1.2、判断一个文件是否存在
BOOL isFileExist = [manager fileExistsAtPath:[NSString stringWithFormat:@"%@%@",document,@"/file.txt"]];//参数是路径+文件名+扩展名
if(isFileExist)
{
NSLog(@"文件已经存在");
}
else
{
NSLog(@"文件不存在");
1.3、创建一个文件
BOOL isCreate = [manager createFileAtPath:[NSString stringWithFormat:@"%@%@",document,@"/file.txt"] contents:nil attributes:nil];//第一个参数是路径+文件名+扩展名
if(isCreate)
{
NSLog(@"创建成功");
}
else
{
NSLog(@"创建失败");
}
}
1.4、创建一个目录
BOOL isDirectory = [manager createDirectoryAtPath:[document stringByAppendingString:@"/ll/pp"] withIntermediateDirectories:YES attributes:nil error:nil];//第一个参数是这次要创建的文件夹的完整路径
if(isDirectory)
{
NSLog(@"目录创建成功");
}
else
{
NSLog(@"目录创建失败");
}
1.5、获得文件大小
NSDictionary *fileDic = [manager attributesOfItemAtPath:[document stringByAppendingString:@"/file.txt"] error:nil];//第一个参数是想看的文件的路径+文件名+扩展名(file.txt)
NSLog(@"%@",[fileDic objectForKey:@" "]);
1.6、遍历文件夹
1.6.1、浅层遍历(只遍历当前路径)
NSArray *shallowArr = [manager contentsOfDirectoryAtPath:document error:nil];//第一个参数就是想要进行浅层遍历的路径
NSLog(@"%@",shallowArr);
1.6.2、深层遍历(遍历当前路径及其所有子路径)
NSArray *deepArr = [manager subpathsOfDirectoryAtPath:document error:nil];//第一个参数就是想要进行深层遍历的路径
NSLog(@"%@",deepArr);
for(NSString *temp in deepArr)
{
if([temp hasSuffix:@".txt"])
{
NSLog(@"%@已经传上服务器了",temp);
}
}
1.7、复制和剪切
1.7.1、复制
一、准备源文件(源文件的路径+文件名+扩展名)
NSString *originalFile = [document stringByAppendingString:@"/file.txt"];
二、准备目标文件(想要复制到的那个路径+文件名+扩展名)
NSString *targetFile = [document stringByAppendingString:@"/ll/mm.mp4"];
三、把源文件复制黏贴到目标位置
BOOL isCopy = [manager copyItemAtPath:originalFile toPath:targetFile error:nil];
if(isCopy)
{
NSLog(@"复制成功");
}
else
{
NSLog(@"复制失败");
}
1.7.2、剪切
一、准备源文件
NSString *cutOriginalFile = [document stringByAppendingString:@"/ll/mm.mp4"];
二、准备目标文件
NSString *cutTargetFile = [document stringByAppendingString:@"/ll/pp/mm.mp4"];
三、移动(源文件消失)
BOOL isMove = [manager moveItemAtPath:cutOriginalFile toPath:cutTargetFile error:nil];
if(isMove)
{
NSLog(@"移动完成");
}
else
{
NSLog(@"移动失败");
}
2、文件内操作
2.1、打开文件(只读reading、只写writing、读写updating三种方式)
NSFileHandle *handle = [NSFileHandle fileHandleForUpdatingAtPath:[document stringByAppendingString:@"/file.txt"]];//参数是一个文件的路径+文件名+扩展名
2.2、读文件
//文件刚打开,光标在最开始
NSData *firstRead = [handle readDataToEndOfFile];//把这个文件从头读到尾
NSString *firstReadStr = [[NSString alloc] initWithData:firstRead encoding:NSUTF8StringEncoding];
NSLog(@"%@",firstReadStr);
2.3、写文件
NSString *secondWriteStr = @"pp";
NSData *secondWriteData = [secondWriteStr dataUsingEncoding:NSUTF8StringEncoding];
[handle writeData:secondWriteData];
注意:无论是读还是写,最后光标都会移动到读和写的结尾,这个结尾根据你读了多少,写了多少来定
2.4、移动光标
2.4.1、移动到最开始
[handle seekToFileOffset:0];
2.4.2、移动到最后
[handle seekToEndOfFile];