1、内存分为五个区域:栈区:储存局部变量;;
堆区:程序运行时动态开辟的空间;
BSS段:没有初始化的全局变量、静态变量;
数据区:初始化的全局变量、静态变量。字符串常量;
代码段:程序编译后的程序代码;
后面三个区域在程序一开始执行的时候,就会存在;地址顺序是从高到低;堆区的地址时从低到高;
内存的泄露:当指向对象的指针被释放,但是指针引用的对象储存的堆空间没有被释放,所以造成了内存泄露(这一块内存空间并没有使用,却没有释放就造成了内存泄漏);
当对象在堆空间释放的时候,再去引用指针,这个指针就是”野指针“;继续引用对象的方法或者成员变量,会报错;一般在释放之后,给指针赋值为nil;
每一个对象中都会有一个无符号长整形引用计数器retainCount属性(8字节),用来计算对象被引用的次数;
2、OC的内存管理分类:1、MAC:手动内存管理;
2、ARC:自动内存回收管理
3、garbage collection(垃圾回收);IOS不支持;
3、随机数的生成使用arc4random开头的方法,传递的参数是最大的范围比如255,生成的最大的数是255;
4、nil:是一个对象值;
Nil:是一个类对象值;
NULL:是一个通用指针;
5、在导入头文件的时候@class与@import的区别:
@class:只是告诉系统这是一个类,并不会检测这个类内部的方法和属性;而且当导入的这个类改变的时候,并不需要重新编译;但是需要在。.m文件中@import早导入一次;而且可以避免循环引入的情况;
@import:会将类的头文件全部导入进来,而且一旦更改,那么必要要重新编译;而且会涉及到循环引用的问题;比如说A类里面导入了B类,B类里面导入了A类,Xcode会报错;
6、retain循环引用的问题:(当两个类互相使用retain引用的时:A类使用B类对象,B类使用A类的对象);
解决方法:1、可以让某一个对象多释放一次(注意释放的顺序呢);
2、让一个引用的时候使用assign、另一个使用retain;
7、使用更改setter、getter方法名字时:setter = XXX:;getter=XXX;注意setter方法后面有冒号;
8、ARC模式下如何兼容非ARC类
让程序兼容ARC和非ARC部分,转变为非ARC -fno-obj-arc
转变为ARC的 -f-obj-arc
选中项目-->再选中target-->Build Phases --> Compile Source;点开后会看到target中的类文件;双击你需要更改的m文件,对添加上面指令;
9、在实现分类的时候,使用@property添加成员变量时,虽然编译的时候不会报错,但是运行的时候会报错;
分类中实现与类同名的方法,会优先使用分类的方法;如果有多个分类实现了类中的同一个方法,这个时候会执行最后编译的那个同名方法;
10、分类非正式协议
非正式协议通常定义为NSObject的类别;所谓非正式协议就是类别,即凡是NSObject或Foundation框架中的类增加的类别,都是非正式协议;
11、Block代码块的定义:
无返回值无参数:void (^Block变量名)() = ( )^{ 代码块的内容 }; 无参数时第二个小括号可以省略;
无返回值有参数:void (^Block变量名)(参数类型个数) = (形参列表 )^{ 代码块的内容 };
有返回值有参数:返回类型 (^Block变量名)(参数类型个数) = (形参列表 )^{ 代码块的内容; 必须有返回值 };
有返回值无参数:返回类型 (^Block变量名)() = ( )^{ 代码块的内容; 必须有返回值 };无参数时第二个小括号可以省略;
11、Copy和 MutableCopy区别
共同点:
当使用这两个关键字的时候,对象都必须满足NSCopying后者NSMutableCopying协议;主要是实现copyWithZone方法;实际上我们调用copy时候。编译器都是帮我们调用copyWithZone方法,这是底层的优化;
两者的使用都会产生一个拷贝,对于对象的更改都不会对另一个不会产生影响;
不同点:
前者是一个浅拷贝,没有有产生一个新的内存地址、但是互不影响,而且会对引用计数+1、拷贝之后是不可变的;
后者是一个深拷贝,产生了一个新的内存地址,对于源对象的引用计数没有影响,拷贝之后是可变的;