博客> Object C Foundation框架
Object C Foundation框架
2019-09-17 19:22 评论:0 阅读:1461 ZXY_Start
ios NSString NSArray 基本数据类型 被忽略的方法 CFString

做iOS 开发快三年了,由于不是计算机出身(之前是做材料的学生,就是制做有机、无机发光材料的哎~),以及对计算机基础知识的缺乏,iOS 开发所使用的语言OC底层的功能了解较少,很多拿来主义,不顾效率内存只为了完成外包项目,也带过大大小小的项目,最近才开始考虑这个问题:OC的基础,这个我一直没吃透啊,只是会用,本人才疏学浅,总结的不会太完整,希望路过的西门大官人可以积极补充,当然swift的项目也带过两个,只是由于后来swift自动升级后,正片代码犹如春节后的祖国大地一样,目前已经极度讨厌,如有需要的同学可以留下邮箱,一起探讨。向版主zenny_chen致敬,如果没有看过版主的一篇文章(我不告诉你们),还真不知道什么是底层(咱起步晚,向大神致敬)。

如果要了解iOS 以及mac的开发必然离不开OC最基础的框架 <Foundation>,里面有我们今后开发经常使用的基本类入:NSString , NSArray , NSValue , NSThread等,该框架所有的类前的NS如果大家看过上映不久的乔布斯传就会明白了。

Foundation框架是在CoreFoundation/CoreFoundation.h的基础上搭建起来的,查看Foundation.h的文件信息,其中第一行为#include <CoreFoundation>,表明此框架通过c/c++的方式被引入到Foundation,里面的文件入CFArray,CFData等是通过C编写的。Foundation 框架的底层是使用C来实现的(在实际编程中可以考虑通过C来处理复杂的数据,当然要考虑ARC机制)。

进入正题:(以下代码均在CommandLine模式中完成)
**struct**
OC声明struct的方式可以和C的方式一样有如下两种:
     `  #import <Foundation>
            struct stu{
                void *name;
                void *addr;

            };

            typedef struct {
                void *name;
                void *addr;
            }stu1;

            int main(int argc, const char * argv[]) {
                @autoreleasepool {
                    struct stu student;
                    stu1 stu_ty;
                    student.name = "Hello";
                    stu_ty.name  = "Hello _ty";
                    printf("%s \n %s \n",student.name,stu_ty.name);
                }
                return 1;
            }

输出结果:Hello Hello _ty 注意:1.struct中不能存在OC中的类入: NSString,需要使用C中的形式如void *addr; 2.OC中的字符串等需要使用@,如@"Hello world"这是告诉编译器(目前是LLVM 7),此段代码是OC代码,如果是C的代码,不需要使用@,如上所示"Hello"` ------------------------------------------------

**NSString 不可变字符串与可变字符串 NSMutableString**
几乎所有的基础数据类型(字符串、数组、字典等)都分为不可变和可变的,这里涉及到常量池和      hashcode的概念(如果有小伙伴了解,希望可以给我一些资料)基于一种优化,应该指的是常量池中的数据存取速度较快。另一个需要注意的地方就是所有的不可变数据类型进行copy时只是浅复制(指针指向同一个内存区),如果想使用深复制,请使用mutableCopy方法进行复制,此时系统会分配一块新的内存给该变量。
比较两个字符串的内容是否相同:[@“” isEqualToString:@"b"];或者[a compare:@"b"] == NSOrderedSame;
比较两个字符串的内存地址是否相同(或者说对象地址)是否相同使用==即可
比较两个字符串的大小使用
`[@"a111" compare:@"a1234"options:NSNumericSearch|NSCaseInsensitiveSearch] == NSOrderedSame`
比较有三种结果NSOrderedAscending , NSOrderedSame, NSOrderedDescending
options代表比较条件,如忽略字母大小写,比较数字等
当然字符串还有其他方法,如根据格式生成指定的内容、查找,可变字符串还可以新增、删减字符串的内   容。
OC字符串与C字符串的转换:
    `const char *name = "Tom";
     NSString *tom = [NSString stringWithUTF8String:name];
     const char *tom_name = [tom cStringUsingEncoding:NSUTF8StringEncoding];
     NSLog(@" OC - >%@ , C -> %s",tom,tom_name);`
结果如下:OC - >Tom , C -> Tom
OC与CFStringRef的转换如下(ARC模式下)
    `NSString *OC_s = @"Test";
     CFStringRef cf_string = (__bridge CFStringRef)OC_s;
     NSString *to_OC_s = (__bridge_transfer NSString *)cf_string;`
(bridge 涉及到的对象归属权问题,将会在下一张内存管理中介绍)
非ARC模式下:
    `NSString *OC_s = @"Test";
     CFStringRef cf_string = (CFStringRef)OC_s;
     NSString *to_OC_s = (NSString *)cf_string;`

------------------------------------------------

**NSArray组数**
数组为存储一对象的有序列表,所以int、NSInteger等非对象需要装箱才可以放入数组中,数组使用nil作为数组的结尾,所以在数组中不能插入nil。
关于数组,只介绍如下方法:
    `NSArray *names = @[@"Tom" , @"Jerry" , @"Alix"];
    [names enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

    }];`
enumerate方法用来便利数组,与我们熟知的for(id one in names)方法稍有不同,其中的options可以指定正序或者倒序遍历。obj表示当前的对象,idx表示当前对象在数组中的位置。

------------------------------------------------

**NSDictionary 字典**
    字典由关键字和对象组成的集合,例如为了简化某些简单的数据模型,如与应用设置相关的开关可以通过字典的形式存放:
`    NSDictionary * dic_info = [NSDictionary dictionaryWithObjects:@[@1 , @0 , @3] forKeys:@[@"is_login" , @"can_play" , @"play_times"]];`
当然实例话的方法很多,只要记住字典是成对出现的,object代表的是对象称之为value,keys代表的是键称之为key,通常我们通过key寻找value,所以,一个key只可能对应一个value(只有可变字典才能改变字典的内容),字典中的value 一定是对象,不能是int等,不能为nil。

------------------------------------------------

**装箱**
由于数组以及字典中只能插入对象,那么问题来了,int类型和struct类型应该如何存入数组中呢?
如果是int、float等类型可以使用NSNumber进行封装
如果是struct 可以通过如下方式
    `struct stu base_data;
     base_data.name = "Ok";
     NSValue * value = [NSValue valueWithBytes:&base_data objCType:@encode(struct stu)];`
开箱
    对于int、float等同样适用NSNumber开箱
    struct开箱方式如下
    `struct stu unar_data ;
    [value getValue:&unar_data];
    printf("%s",unar_data.name);`

对于nil 可以使用NSNull来代替

收藏
0
sina weixin mail 回到顶部