美文网首页
iOS知识点总结(3)

iOS知识点总结(3)

作者: 飞哥漂流记 | 来源:发表于2019-12-13 09:57 被阅读0次

1. 能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?

不能向编译后得到的类中增加实例变量

能向运行时创建的类中添加实例变量。

原因:

因为编译后的类已经注册在 runtime 中,类结构体中的 objc_ivar_list 实例变量的链表和 instance_size 实例变量的内存大小已经确定,同时 runtime 会调用 class_setIvarLayout 或 class_setWeakIvarLayout 来处理 strong weak 引用。所以不能向存在的类中添

加实例变量。

运行时创建的类是可以添加实例变量,调用 class_addIvar 函数。但是得在调用 objc_allocateClassPair 之后,

objc_registerClassPair 之前

2. 发送10个网络请求,然后再接收到所有回应之后执行后续操作,如何实现?

GCD信号量,队列组

做法:通过dispatch_group_t来实现,将每个请求放入到Group中,将合并成大图的操作放在dispatch_group_notify中实现。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^{ /*加载图片1 / });

dispatch_group_async(group, queue, ^{ /加载图片2 / });

dispatch_group_async(group, queue, ^{ /加载图片3 */ });

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

// 合并图片

});

dispatch_group_enter()和dispatch_group_leave()

3.  iOS数据本地存储方式?

1沙盒

Document:适合存储重要的数据, iTunes同步应用时会同步该文件下的内容,(比如游戏中的存档)

Library/Caches:适合存储体积大,不需要备份的非重要数据,iTunes不会同步该文件

Library/Preferences:通常保存应用的设置信息, iTunes会同步

tmp:保存应用的临时文件,用完就删除,系统可能在应用没在运行时删除该目录下的文件,iTunes不会同步

// 获取Documents目录的路径

NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

// 得到Document目录下的fileName文件的路径

NSString *filePath = [documentPath stringByAppendingPathComponent:fileName];

//获取Library/Caches目录路径

NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;

//获取Library/Caches目录下的fileName文件路径

NSString *filePath = [path stringByAppendingPathComponent:fileName];

//获取temp路径

NSString *tmp = NSTemporaryDirectory();

//获取temp下fileName文件的路径

NSString *filePath = [tmp stringByAppendingPathComponent:fileName];

2、Plist

可以把字典或数组直接写入到文件中。另外,NSString、NSData、NSNumber等类型,也可以使用writeToFile:atomically:方法直接将对象写入文件中,只是Type为空。

// 要保存的数据

NSDictionary *dict = [NSDictionary dictionaryWithObject:@"iOS cookbook" forKey:@"bookName"];

// 获取路径.

NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.plist"];

// 写入数据

[dict writeToFile:filePath atomically:YES];

3、NSKeyedArchiver归档 / NSKeyedUnarchiver解档

如果想对一个自定义对象进行归档解档,首先要让对象遵守NSCoding协议。

其中:NSCoding协议有2个方法:

- (void)encodeWithCoder:(NSCoder *)aCoder

归档时调用这个方法,在方法中使用encodeObject:forKey:归档变量。

- (instancetype)initWithCoder:(NSCoder *)aDecoder

解档时调用这个方法,在方法中使用decodeObject:forKey读出变量。

//类方法,运用NSKeyedArchiver归档数据

+ (void)saveConfig:(DDAppConfigModel *)config

{

    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

    NSString *path = [docPath stringByAppendingPathComponent:@"DDAppConfigModel.plist"];

    [NSKeyedArchiver archiveRootObject:config toFile:path];

}

//类方法,使用NSKeyedUnarchiver解档数据

+ (DDAppConfigModel *)getConfig

{

    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

    NSString *path=[docPath stringByAppendingPathComponent:@"DDAppConfigModel.plist"];

    DDAppConfigModel *config = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

    return config;

}

//类方法,运用NSKeyedArchiver归档数据

+ (void)saveConfig:(DDAppConfigModel *)config

{

    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

    NSString *path = [docPath stringByAppendingPathComponent:@"DDAppConfigModel.plist"];

    [NSKeyedArchiver archiveRootObject:config toFile:path];

}

//类方法,使用NSKeyedUnarchiver解档数据

+ (DDAppConfigModel *)getConfig

{

    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;

    NSString *path=[docPath stringByAppendingPathComponent:@"DDAppConfigModel.plist"];

    DDAppConfigModel *config = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

    return config;

}

4.NSUserDefaults

一般使用它来进行一些设置的记录,比如用户ID,开关是否打开等设置。通过键值对的方式记录设置。

NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。

存数据的方法:

NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];

NSString *name =@”default string“;

[defaults setObject:firstName forKey:@"name"];

[defaults synchronize];//用synchronize方法把数据持久化到standardUserDefaults数据库

去数据的方法:

//读取文件

NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];

NSString *name=[defaults objectForKey:@"name"];

NSInteger age=[defaults integerForKey:@"age"];

5、SQLite3

- (void)openDB{

    //获取数据库文件路径

    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    NSString *fileName = [doc stringByAppendingPathComponent:@"students.sqlite"];

    //将OC字符串转换为c语言的字符串

    const char *cfileName = fileName.UTF8String;

    //打开数据库文件(如果数据库文件不存在,那么该函数会自动创建数据库文件)

    int result = sqlite3_open(cfileName, &_db);

    if (result == SQLITE_OK) {//打开成功

        NSLog(@"成功打开数据库");

    }else{

        NSLog(@"打开数据库失败");

    }

}

- (void)createTable{

    //创建表

    const char *sql = "CREATE TABLE IF NOT EXISTS t_student(id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,age integer NOT NULL);";

    char *errmsg= NULL;

    int result = sqlite3_exec(_db, sql, NULL, NULL, &errmsg);

    if (result==SQLITE_OK) {

        NSLog(@"创建表成功");

    }else{

        NSLog(@"创建表失败---%s",errmsg);

    }

}

- (void)insertData{

    //插入数据

    for (int i=0; i<10; i++) {

        //拼接sql语句

        NSString *name = [NSString stringWithFormat:@"yixiangboy--%d",arc4random_uniform(100)];

        int age = arc4random_uniform(20)+10;

        NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student (name,age) VALUES ('%@',%d);",name,age];

        //执行SQL语句

        char *errmsg = NULL;

        sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg);

        if (errmsg) {//如果有错误信息

            NSLog(@"插入数据失败--%s",errmsg);

        }else{

            NSLog(@"插入数据成功");

        }

    }

}

6、Core Data 

7、FMDB

FMDB封装了SQLite的C语言API,更加面向对象。

FMDatabase:可以理解成一个数据库。

FMResultSet:查询的结果集合。

FMDatabaseQueue:运用多线程,可执行多个查询、更新。线程安全。

创建数据库 打开数据库

NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.db"];

FMDatabase *db = [FMDatabase databaseWithPath:path];

if (![db open])

{    db = nil;

    return;}

创建表

使用集合语句来进行表的创建

NSString *sql = @"create table bulktest1 (id integer primary key autoincrement, x text);"

                "create table bulktest2 (id integer primary key autoincrement, y text);"

                "create table bulktest3 (id integer primary key autoincrement, z text);"

                "insert into bulktest1 (x) values ('XXX');"

                "insert into bulktest2 (y) values ('YYY');"

                "insert into bulktest3 (z) values ('ZZZ');";

success = [db executeStatements:sql];

查询

使用executeQuery 来执行查询语句,FMResultSet来进行存储查询的结果。

FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];

while ([s next]) {

    //retrieve values for each record

}

更新

通过调用- (BOOL)executeUpdate:(NSString*)sql withParameterDictionary:(NSDictionary *)arguments执行插入、删除或者更新数据。

NSString *sql = ![rs next] ? INSERT_STATEMENT : UPDATE_STATEMENT;

BOOL success = [db executeUpdate:sql withParameterDictionary:[self pr_toDBDictionary]];

if (!success)

{

    STLogDBLastError(db);

    result = NO;

    return;

}

多线程操作数据库:

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];

[queue inDatabase:^(FMDatabase *db) {

    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1];

    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2];

    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3];

    FMResultSet *rs = [db executeQuery:@"select * from foo"];

    while ([rs next]) {

        …

    }

}];

相关文章

网友评论

      本文标题:iOS知识点总结(3)

      本文链接:https://www.haomeiwen.com/subject/vnqxnctx.html