OC语言笔记(六):OC单例、NSData和文件操作

来源:互联网 发布:java图形接口 编辑:程序博客网 时间:2024/06/13 18:44

一、什么是单例

   1、一个单例,表示在一个应用的生命周期中,这个类的对象只能被实例化一次,也就是说一个类只能有一个对象。

   2、单例的作用:因为,在一个应用中,一个类只有这一个单例对象,所以不管在A还是B还是。。。。中,只要实例化出来,都是同样的一个对象,所以我们可以通过这个对象来进行传值(举例:这个对象有N个属性,其中一个属性是等级,我们在A中给这个对象的等级属性赋值为X,那么不管到任何地方,只要实例化出来这个对象,他的等级属性的值就都是X,我们可以取出来使用)


注意:单例中的alloc无需手动内存释放,因为单例是全局范围内的对象,系统会在程序结束是自动释放,如果提前手动释放,会引起错误!!!


   3、单例在AppDelegate.m文件中的写法

    //非单例类

    NormalClass *normalOne = [NormalClassalloc];//做一个对象

    normalOne.name =@"lily";//为这个对象的name属性赋值为lily

    NSLog(@"%@",normalOne.name);//用点语法取值

    

    NormalClass *normalTwo = [NormalClassalloc];//做一个对象

    NSLog(@"%@",normalTwo.name);//这次打印为空

    //思考:     

    //通过下面的打印,可以看出这两个alloc出来的对象的地址是不同的

    NSLog(@"%@",normalOne);

    NSLog(@"%@",normalTwo);

    

    //单例类(注意要用咱们自己写的单例方法)

    SingleClass *singleOne = [SingleClassshareInstance];//用单例方法做一个对象

    singleOne.name = @"lucy";

    NSLog(@"%@",singleOne.name);

    

    SingleClass *singleTwo = [SingleClassshareInstance];//用单例方法做一个对象

    NSLog(@"%@",singleTwo.name);//可以成功打印出twoname属性的值

    //我们并没有给singleTwo.name赋值,但是依然可以取出他的值,就是因为,我们使用了单例的方法,创建出来的singleOnesingleTwo其实是同一个对象(因为在单例方法中,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方法来只做单例

    staticdispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        //大括号中的代码在整个应用中只会被执行一次

   5.3、把上面的静态全局变量赋值,进行实例化

        single = [SingleClassalloc];

    });

   5.4、把静态全局指针变量返回

    return single;

}

@end


二、NSData操作方法

 1NSStringNSData之间的转换

    NSString *str = @"abcdefg";

    

    NSData *strData = [strdataUsingEncoding:NSUTF8StringEncoding];//把字符串变成data

    NSLog(@"%@",strData);

    

    NSString *backStr = [[NSStringalloc] initWithData:strDataencoding:NSUTF8StringEncoding];

    NSLog(@"%@",backStr);

    

    2、对象与NSKeyedArchiver之间的转换

2.1数组与NSData之间的转换

    NSArray *arr = @[@"aa",@"bb"];

    

    NSData *arrData = [NSKeyedArchiverarchivedDataWithRootObject:arr];//把对象变成data,一次只能把一个对象变成一个data

    NSLog(@"%@",arrData);

    

    NSArray *backArr = [NSKeyedUnarchiverunarchiveObjectWithData:arrData];//data变成对象

    NSLog(@"%@",backArr);


     2.2、字典NSData之间的转换

    //请做一个字典,两个keynamelilyage18,用上面方法变成data

NSDictionary *a7 = [NSDictionarydictionaryWithObjectsAndKeys:@"lily",@"name",@"18",@"age",nil];

NSData *a8 = [NSKeyedArchiverarchivedDataWithRootObject:a7];

NSDictionary *a9= [NSKeyedUnarchiverunarchiveObjectWithData: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 = [NSMutableDatadataWithCapacity:0];

    

     3.2.2、用alloc的方法做一个archiver的对象,初始化这个对象的时候,要用一个可变data,这个archiver将把很多个对象转成data,这些data都存在了这个可变data

    NSKeyedArchiver *archiver = [[NSKeyedArchiveralloc] 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.2Data转换成对象的步骤

#pragma mark data中根据之前设置好的key找到对应的对象

    

     3.2.1、做一个NSKeyedUnArchiver对象,初始化的时候用一个data,这个data里存着很多个对象

    NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiveralloc] 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 = [NSFileManagerdefaultManager];//其实是一个单例对象

    //接下来的对文件的操作都是用这个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:nilattributes:nil];//第一个参数是路径+文件名+扩展名

        if(isCreate)

        {

            NSLog(@"创建成功");

        }

        else

        {

            NSLog(@"创建失败");

        }

    }

    

      1.4、创建一个目录

    BOOL isDirectory = [managercreateDirectoryAtPath:[document stringByAppendingString:@"/ll/pp"]withIntermediateDirectories:YESattributes:nilerror:nil];//第一个参数是这次要创建的文件夹的完整路径

    if(isDirectory)

    {

        NSLog(@"目录创建成功");

    }

    else

    {

        NSLog(@"目录创建失败");

    }

    

      1.5、获得文件大小

    NSDictionary *fileDic = [managerattributesOfItemAtPath:[document stringByAppendingString:@"/file.txt"]error:nil];//第一个参数是想看的文件的路径+文件名+扩展名(file.txt)

    NSLog(@"%@",[fileDicobjectForKey:@""]);

    

      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 *tempin 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:targetFileerror: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:cutTargetFileerror:nil];

    if(isMove)

    {

        NSLog(@"移动完成");

    }

    else

    {

        NSLog(@"移动失败");

    }


    2、文件内操作

    2.1、打开文件(只读reading、只写writing、读写updating三种方式)

    NSFileHandle *handle = [NSFileHandlefileHandleForUpdatingAtPath:[document stringByAppendingString:@"/file.txt"]];//参数是一个文件的路径+文件名+扩展名

     2.2、读文件

    //文件刚打开,光标在最开始

    NSData *firstRead = [handle readDataToEndOfFile];//把这个文件从头读到尾

    NSString *firstReadStr = [[NSStringalloc] initWithData:firstReadencoding: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];


0 0