首页 > 其他分享 >IOS开发学习日记(九)

IOS开发学习日记(九)

时间:2024-05-28 18:29:39浏览次数:23  
标签:nil self IOS 学习 NSString void key 序列化 日记

目录

IOS沙盒机制和文件结构

IOS文件管理

NSFileManager

NSFileHandle

简单实现创建、查询、删除文件及追加内容

IOS中的序列化

NSCoder

NSKeyedArchiver

NSCoding

 简单实现数据的序列化与反序列化

开源存储方案对比分析

NSUserDefault

开源框架


IOS沙盒机制和文件结构

 沙盒机制:App只能访问对应的文件夹及相关资源,App之间无法共享文件等资源

Document:可以进行备份和恢复,体积较大,一般存档用户数据

Library:开发者最常使用的文件夹,可以自定义子文件夹

        Preference:用户偏好设置,NSUserDefault,支持备份

        Cache:不需要缓存的,体积较大,一般的删除缓存操作

        ......

SystemData:系统文件

tmp:临时文件不会备份,启动时可能会被删除

IOS获取沙盒地址:NSPathUtilities

-(void) _getSandBoxPath{
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSLog(@"");
}

IOS文件管理

NSFileManager

        1.单例,提供App内文件&文件夹管理功能

        2.创建、删除、查询、移动、复制文件

        3.读取文件内容&属性

        4.通过NSURL或者NSString作为Path

        NSFileManagerDelegate:提供移动、复制、删除等操作的具体自定义实现

NSFileHandle

        1.读取文件&写文件

        2.读取指定长度&在指定位置追加/截断

        3.截断&立即刷新

        4.常用语追加数据

// 创建
+ (nullable instancetype)fileHandleForReadingAtPath:(NSString *)path;
+ (nullable instancetype)fileHandleForWritingAtPath:(NSString *)path;
+ (nullable instancetype)fileHandleForUpdatingAtPath:(NSString *)path;

// 读&写
- (NSData *)readDataOfLength:(NSInteger)length;
- (void)seekToFileOffset:(unsigned long long)offset;
- (void)writeData:(NSData *)data;

简单实现创建、查询、删除文件及追加内容

-(void) _getSandBoxPath{
    
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [pathArray firstObject];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *dataPath = [cachePath stringByAppendingPathComponent:@"GSCData"];    // cache文件夹下创建GSCData子文件夹
    
    NSError *createError;
    [fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&createError];
    
    NSString *listDataPath = [dataPath stringByAppendingPathComponent:@"list"]; // 创建文件
    NSData *listData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding];
    
    [fileManager createFileAtPath:listDataPath contents:listData attributes:nil];
    
    //查询文件
    BOOL fileExist = [fileManager fileExistsAtPath:listDataPath];
    
//    //删除文件
//    if(fileExist){
//        [fileManager removeItemAtPath:listDataPath error:nil];
//    }
//    
    // 追加文件内容
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:listDataPath];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:[@"def" dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandle synchronizeFile];
    [fileHandle closeFile];

}

IOS中的序列化

NSCoder

        1.归档(序列化)&解归档(反序列化)

        2.提供简单的函数,在Object和二进制数据见进行转换

        3.抽象类 具体功能需要子类实现

// encode
- (void)encodeObject:(nullable id)object forKey:(NSString *)key;
- (void)encodeBool:(BOOL)value forKey:(NSString *)key;
- (void)encodeInt:(int)value forKey:(NSString *)key;
- (void)encodeInt32:(int32_t)value forKey:(NSString *)key;
- (void)encodeInt64:(int64_t)value forKey:(NSString *)key;
- (void)encodeFloat:(float)value forKey(NSString *)key;
- (void)encodeDouble:(double)value forKey(NSString *)key;

//decode 
- (nullable id)decodeObjectForKey:(NSString*)key;
- (BOOL)decodeBoolForKey:(NSString *)key;
- (int)decodeIntForKey:(NSString *)key;
- (int32_t)decodeInt32ForKey:(NSString *)key;
- (int64_t)decodeInt64ForKey:(NSString *)key;
- (float)decodeFloatForKey:(NSString *)key;
- (double)decodeDoubleForKey:(NSString *)key;

为了向前向后兼容,不依赖顺心,所以需要将非基本数据对应到key存储

NSKeyedArchiver

        1.NScoder的子类

        2.提供简单的函数,在Object和二进制数据之间进行转换

        3.提供基本的delegate

        4.需要Object自己处理Key-Value的对应关系

NSCoding

对于Objecy等序列化&反序列化协议

·NSArray&NSDictionary等类型系统已经实现协议

·NSSecureCoding

        1.解决文件替换攻击

        2.序列化时规定Class

 简单实现数据的序列化与反序列化

//实现NSSecureCoding

//
//  GSCListItem.h
//  GSCApp1
//
//  Created by gsc on 2024/5/23.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN


/*
 列表结构化属性
 */

@interface GSCListItem : NSObject <NSSecureCoding>

@property (nonatomic, copy, readwrite)  NSString * category;
//@property (nonatomic, copy, readwrite)  NSString * isContent;
@property (nonatomic, copy, readwrite)  NSString * picUrl;
@property (nonatomic, copy, readwrite)  NSString * uniquekey;
@property (nonatomic, copy, readwrite)  NSString * title;
@property (nonatomic, copy, readwrite)  NSString * date;
@property (nonatomic, copy, readwrite)  NSString * authorName;
@property (nonatomic, copy, readwrite)  NSString * articleUrl;

-(void) configWithDictionary:(NSDictionary *) dictionary;

@end

NS_ASSUME_NONNULL_END


//
//  GSCListItem.m
//  GSCApp1
//
//  Created by gsc on 2024/5/23.
//

#import "GSCListItem.h"

@implementation GSCListItem

#pragma mark - NSSecureCoding

-(nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if(self){
        self.category = [aDecoder decodeObjectForKey:@"category"];
        self.picUrl = [aDecoder decodeObjectForKey:@"thumbnail_pic_s"];
        self.uniquekey = [aDecoder decodeObjectForKey:@"uniquekey"];
        self.title = [aDecoder decodeObjectForKey:@"title"];
        self.date = [aDecoder decodeObjectForKey:@"date"];
        self.authorName = [aDecoder decodeObjectForKey:@"author_name"];
        self.articleUrl = [aDecoder decodeObjectForKey:@"url"];
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.category forKey:@"category"];
    [aCoder encodeObject:self.picUrl forKey:@"thumbnail_pic_s"];
    [aCoder encodeObject:self.uniquekey forKey:@"uniquekey"];
    [aCoder encodeObject:self.title forKey:@"title"];
    [aCoder encodeObject:self.date forKey:@"date"];
    [aCoder encodeObject:self.authorName forKey:@"author_name"];
    [aCoder encodeObject:self.articleUrl forKey:@"url"];

}

#pragma mark - NSSecureCoding
+(BOOL)supportsSecureCoding{
    return YES;
}

#pragma mark - public method#pragma mark - NSSecureCoding

- (void)configWithDictionary:(NSDictionary *)dictionary {
    self.category = [dictionary objectForKey:@"category"];
    self.picUrl = [dictionary objectForKey:@"thumbnail_pic_s"];
    self.uniquekey = [dictionary objectForKey:@"uniquekey"];
    self.title = [dictionary objectForKey:@"title"];
    self.date = [dictionary objectForKey:@"date"];
    self.authorName = [dictionary objectForKey:@"author_name"];
    self.articleUrl = [dictionary objectForKey:@"url"];
}


@end

//
//  GSCListLoader.m
//  GSCApp1
//
//  Created by gsc on 2024/5/20.
//

#import "AFNetworking/AFNetworking.h"
#import "GSCListItem.h"
#import "GSCListLoader.h"

@implementation GSCListLoader

- (void)loadListDataWithFinishBlock:(GSCListLoaderFinishBlock)finishBlock {
    NSString *urlString = @"http://v.juhe.cn/toutiao/index?type=top&key=97ad001bfcc2082e2eeaf798bad3d54e";
    NSURL *listURL = [NSURL URLWithString:urlString];
    NSURLSession *session = [NSURLSession sharedSession];
    
    __weak typeof(self) weakself = self;
    NSURLSessionTask *dataTask = [session dataTaskWithURL:listURL
                                        completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
        __strong typeof(weakself) strongSelf = weakself;
        NSError *jsonError;
        id jsonObj = [NSJSONSerialization JSONObjectWithData:data
                                                     options:0
                                                       error:&jsonError];

        NSArray *dataArray = [((NSDictionary *)[((NSDictionary *)jsonObj) objectForKey:@"result"]) objectForKey:@"data"];
        NSMutableArray *listItemArray = @[].mutableCopy;

        for (NSDictionary *info in dataArray) {
            GSCListItem *listItem = [[GSCListItem alloc] init];
            [listItem configWithDictionary:info];
            [listItemArray addObject:listItem];
        }
        [strongSelf _archiveListDataWithArray:listItemArray.copy];
        dispatch_async(dispatch_get_main_queue(), ^{
                           if (finishBlock) {
                               finishBlock(error == nil, listItemArray);
                           }
                       });
    }];

    [dataTask resume];
}

-(void) _archiveListDataWithArray:(NSArray<GSCListItem *> *)array{
    
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [pathArray firstObject];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *dataPath = [cachePath stringByAppendingPathComponent:@"GSCData"];    // cache文件夹下创建GSCData子文件夹
    
    NSError *createError;
    [fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&createError];
    
    NSString *listDataPath = [dataPath stringByAppendingPathComponent:@"list"]; // 创建文件
//    NSData *listData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding];
    
    // 数据序列化
    NSData *listData = [NSKeyedArchiver archivedDataWithRootObject:array requiringSecureCoding:YES error:nil];
    
    [fileManager createFileAtPath:listDataPath contents:listData attributes:nil];
    
    NSData *readListData = [fileManager contentsAtPath:listDataPath];
    
    // 数据反序列化
    id unarchiveObj = [NSKeyedUnarchiver unarchivedObjectOfClasses: [NSSet setWithObjects:[NSArray class], [GSCListItem class], nil]
    fromData: readListData error:nil]; 
    
}


@end

开源存储方案

NSUserDefault

提供简单的key-value存储

        1.单例,存取轻量级的数据                        2.支持基本的数据类型

        3.一般用于用户的偏好设置                        4.保存Integer Float Double Bool

        5.升级安装后还可以继续使用                    6.保存NSArray NSData NSString NSDictionary

        7.文件存储在/Library/Preference下           7.复杂Model需要转化成NSData

-(void) _archiveListDataWithArray:(NSArray<GSCListItem *> *)array{
    
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [pathArray firstObject];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *dataPath = [cachePath stringByAppendingPathComponent:@"GSCData"];    // cache文件夹下创建GSCData子文件夹
    
    NSError *createError;
    [fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&createError];
    
    NSString *listDataPath = [dataPath stringByAppendingPathComponent:@"list"]; // 创建文件
//    NSData *listData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding];
    
    // 数据序列化
    NSData *listData = [NSKeyedArchiver archivedDataWithRootObject:array requiringSecureCoding:YES error:nil];
    
    [fileManager createFileAtPath:listDataPath contents:listData attributes:nil];
    
    NSData *readListData = [fileManager contentsAtPath:listDataPath];
    
    // 数据反序列化
    id unarchiveObj = [NSKeyedUnarchiver unarchivedObjectOfClasses: [NSSet setWithObjects:[NSArray class], [GSCListItem class], nil]
    fromData: readListData error:nil];
    
    [[NSUserDefaults standardUserDefaults] setObject:listData forKey:@"listData"];
    NSData *testListData = [[NSUserDefaults standardUserDefaults] dataForKey:@"listData"];
    id unarchiveObjTest = [NSKeyedUnarchiver unarchivedObjectOfClasses: [NSSet setWithObjects:[NSArray class], [GSCListItem class], nil]
    fromData: testListData error:nil];
}

开源框架

        系统级存储:NSUserData、keychain、通过NSKeyedArchiver归档后存文件、数据库CoreData

        key-value类型:LevelDB/MMKV/Realm

        关系数据库类型:SQLite/FMDB/WCDB

 

标签:nil,self,IOS,学习,NSString,void,key,序列化,日记
From: https://blog.csdn.net/gsc711/article/details/139181058

相关文章

  • IOS开发学习日记(十)
    目录缓存新闻数据和已读状态优化网络和存储流程 IOS中线程基础知识NSThreadGCD(GrandCentralDispatch)的常用方法分析和使用 GCD中的队列GCD的使用NSOperationRunLoop​​​​​​​缓存新闻数据和已读状态·使用NSKeyedArchiver保存列表数据    加载本......
  • 学习方法--NLP入门
    1.了解NLP的最基本知识        Jurafsky和Martin的SpeechandLanguageProcessing是领域内的经典教材,对于NLP任务有基本认识,遇到问题知道在书的哪个地方还是非常有意义的。去做一个语言模型的问题,实现神经网络模型之前,第一步要去写一个bigram或者trigram的语言模......
  • 初中生学习掌握这几点,有助于你提高学习成绩,家长也需要了解
    初中是奠定基础的阶段,一旦形成好的学习习惯,不仅整个初中孩子的学习都非常高效,而且到了高中,这些良好的习惯也会约束自己,这对于孩子培养自主学习能力都是很有帮助的,那么初中生需要具备哪些学习习惯呢?具体我做了总结,希望对大家有所帮助!一、做好学习计划的习惯学习一......
  • Jenkins学习(三)--Secret
    一、JenkinsSecret的操作方法①启动Jenkins后进入仪表板中的系统管理,选择凭据管理②点击已经可用的全球商店,单击全局凭据,然后单击添加凭据。③类型选择为Secret,范围选择全局,在Secret处粘贴从postman处复制的api密钥(不知道密钥怎么获取可以参考前面的Jenkins文章),id自定......
  • 阿赵UE引擎C++编程学习笔记——文件夹操作和文件读写
      大家好,我是阿赵。  这次学习一下在UE里面使用C++的API操作文件读写和文件夹操作。一、UE引擎获取相关路径  获取到路径一般是相对路径,使用FPaths::ConvertRelativePathToFull转换后,可以获得完整的绝对路径。FStringcontentDir=FPaths::ProjectContentDir();......
  • 前端菜鸡流水账日记 -- threejs和cesium
    哈喽哇大家,今天来点不一样的,主要是因为今天没有后台系统的修改,所作的修改是在以cesium为基础的项目上,用threejs渲染一个模型,并且可以具有显示/隐藏的功能,那下边就让我们来看看怎么实现的把~--------------------------------------------------------------------------------......
  • Day19学习Java
    什么是注解java.annotation包Annotation是从JDK1.5开始引入的新技术,注解即可以对程序员解释又可以对程序解释注解与注释的区别注释:对程序员解释代码信息注解:对程序和程序员解释代码信息注解的所用不是程序本身,可以对程序作出解释(与注释(comment)类似)可以被其他程序......
  • C语言学习——break语句,continue语句,signed与unsigned,再论数据类型
    目录一、break语句二、continue语句 三、signed与unsigned1.当程序运行时,如果发生了越界:2.有符号与无符号 四、再论数据类型1.C语言中的sizeof关键字2.C语言中的奇葩整型(long)3.数据类型的本质区别一、break语句1、break语句可以结束当前循环的执行2、执行完brea......
  • 基于SpringBoot+Vue+uniapp的互助学习的详细设计和实现(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • Python学习笔记-文件操作与CSV格式
    文件打开和关闭程序中的数据都存储在内存中,当程序执行完毕后,内存中的数据将丢失。文件可以用来进行数据的长期保存。open函数打开一个要做读/写操作的文件,打开文件后会返回一个文件对象,利用该文件对象可完成数据的读写操作。其常用形式为:open(filename,mode='r')#file......