2019-08-15

一、OC基本数据类型


20190807141925.jpg

计算一下他们的取值范围:

以int 为例:int所在4个字节 1Btye = 8bit。 共32位,其中一位需要用来表示正负,还剩下31位。2^31 = 2147483648。因为存在0这个数字,所以正数的范围要-1。及-2147483648 到 2147483647。

注意:当需求标明字符串的长度是字数的长度还是字符的长度,以 name 为例,我们平时使用时就是4位的长度,占用4个Btye的大小的内存。以 苹果开发 为例,我们平时使用时也是以4的长度来计算,但是实际上1个中文字符是占用2个Btye,所以 苹果开发 这4个字是占用8Btye的大小的内存。

二、block的个人理解

这里我们就详细的看block的底层到底是个什么样的东西了,看的多,忘的也快!

我的理解就是block也是一个OC对象,包含了isa指针(isa理解为这个对象到底是何类型的对象,例如我们创建一个NSString的对象,那么isa就是指向这个类对象)。能够联系上下文,处理结果,并把结果返回到当前的界面供我们使用。

先看两个问题,1、为什么局部变量无法在block块中赋值?2、常见问题,为什么block会存在导致循环引用的问题?

1、为什么局部变量无法在block块中赋值

首先block我们一般都是copy到堆中使用的(如果不copy到堆中,那么在作用域执行完成后,就会被释放掉,还如何实现回调处理的作用呢?),局部变量都是存在于栈中,所以一般blcok中都只是能使用局部变量的表示。注意这个值也是copy进来的。如果用__block修饰后,拷贝到block里面的就是指向变量的指针,所以我们就可以修改变量的值。

2、为什么block会存在导致循环引用

其实很简单,我们在使用self调用的一个blcok。eg self.callback = ^{NSLog(@"callback: %@",self);} 这样就会导致循环的引用,平时我喜欢用类方法后面跟一个block的回调来实现网络请求,这样就不用采用弱引用的方式去避免循环引用了,因为它们压根就没有相互引用。

三、NSDictionary的底层原理

NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的。所以我也经常看到有的大神 直接自己写hash表来做缓存,效率要比NSCache高。

hash表的本质是一个数组,hash表的工作原理:

假设该hash表的长度是 n。那么我们通过一个统一的hash算法,例如取余,用对象的hash值(h)取余(h%n)来表示该对象所存在的位置。直接通过数组的取值的方式,就可以获取到该对象的值。

例如hash 表的长度是 16 那么 一个对象的hash值是3,然后取余得到了 3 那么这个对象就是存在这个hash表的第四个位置中。我的理解是每个对象都有自己对应的hash算法。这也是为什么字符串可以作为字典的key的原因吧。所以我们可以理解我们在比较两个对象是否相等的时候,可以先比较hash值,如果hash值都不一样,那么肯定这两个对象是不一样的。如果hash值一样,则再便利这个hash表中这个hash值位置的链表。

这里提到了链表,那么我们在对链表进行基础的解析。


LinkList *creat(int n){

LinkList *head, *node, *end;//定义头节点,普通节点,尾部节点;

head = (LinkList*)malloc(sizeof(LinkList));//分配地址

end = head;        //若是空链表则头尾节点一样

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

node = (LinkList*)malloc(sizeof(LinkList));

scanf("%d", &node->score);

end->next = node;

end = node;

}

end->next = NULL;//结束创建

return head;

}

从上面的代码可以看出来,所谓链表就是在上一个节点中存放着下一个节点的地址,当下一个地址为null时则表示链表结束。这里需要说明一下 链表和数组这两个常用的基本数据结构有何优缺点。数组在内存中是连续存在的,所以当我们在删除或者是增加数据时,因为为了保证内存的连续性,那么在插入或者删除的数据往后的内存地址都需要变化。而链表在插入或者删除时,则只需要在插入或者删除对象的时候,先断开链表,然后重新链接就行。所以效率要比数组高。但是数组的查询效率要比链表高,查询数组则只需要查询位置就行,而链表则需要一点一点的从第一位往后遍历。而且链表会节省空间,因为链表不需要内存的连续性。

image
image

双向链表就是能够向后查询,具体操作其实也和单向链表差不多。

循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。

你可能感兴趣的:(2019-08-15)