Objective-C基础语法学习笔记二
内存中的五大区域
1.栈( 存储局部变量)局部变量,当局部变量的作用域被执行完毕之后,这个局部变量就会被系统立即回收。
2.堆(程序员手动申请的字节空间 malloc calloc realloc 函数)OC对象使用C函数申请的空间
3.BSS段(存储未被初始化的全局变量/静态变量,一旦初始化就回收,并转存到数据段中)
4.数据段(常量区)存储已被初始化的全局变量 静态变量 常量数据
5.代码段 存储代码 程序结束的时候,系统自动回收存储在代码段中的数据
栈/BSS段/数据段/代码段存储在它们中的数据的回收,是由系统自动完成的
分配在堆中的OC对象,系统不会自动回收,直到程序结束的时候才回收
垃圾回收
引用计数器(retainCount)
1.每个对象都有一个属性,叫做retainCount,为引用计数器 类型是unsigned long 占据8个字节,用来记录当前对象的被引用次数。默认为1
2.多一人使用的时候,引用计数器加1,少一人使用的时候,引用计数器减1
3.引用计数器为0时,无人使用 ,系统自动回收
操作引用计数器
1.为对象发送一条retain消息,对象的引用计数器加一
2.为对象发送一条release消息,对象的引用计数器减一
3.为对象发送一条retainCount消息,就可以取到对象的引用计数器的值。
在对象被回收时,会自动调用对象的dealloc方法
野指针
C语言中的野指针:定义1个指针变量。没有初始化,这个指针指向一个垃圾值,指向随机的空间,这个指针就是野指针
OC中的野指针:指针指向的对象已经被回收了,这样的指针就叫做野指针。
僵尸对象
1个已经被释放的对象,但这个对象所占的空间还没有分配给别人,这样的对象叫做僵尸对象。
使用野指针去访问僵尸对象的时候:
当僵尸对象占用的空间还没分配给别人的时候,可以访问到
当僵尸对象占用的空间分配给了别人使用的时候,就不能访问到
无法 retain 复活一个对象
当1个指针的值为nil 通过这个指针去调用对象的方法的时候。不会报错 而是没有任何反应
内存管理分类
MRC: Manual Reference Counting 手动引用计数,手动内存管理
手动发送retain/release消息
ARC: Automatic Reference Counting 自动应用计数,自动管理内存
内存泄露
造成泄漏的场景:
1.有对象的创建,而没有对应的release
2.retain的次数和release的次数不匹配
类加载
类加载
1.在创建对象的时候 需要访问类
2.声明一个类的 变量指针也会访问类
在程序运行期间当某个类被第一次访问到的时候,会讲这个类存储到内存中的代码段区域,这个过程叫做类加载。
一旦类被加载到代码段以后,直到程序结束的时候才会被释放
对象在内存中的存储
Person *p1 对象指针存放在栈内存中,只能存储地址
[Person new] 创建对象
new所做的事情
1.在堆内存中申请一个合适大小的空间
2.在这个空间中根据类的模板创建对象,把类的属性声明给对象
3. 初始化对象的属性,
若为基本类型,初始化为0;
若为C语言指针类型,初始化为null
若为OC指针类型,初始化为nil
4.返回对象在堆中的地址赋值给指针变量
对象中的isa 指针指向 类在代码段中的地址
注意:
1.对象中只有属性(外加一个isa属性),没有方法
2.访问对象属性,根据指针中的地址,找到堆内存中的对象的属性,从而实现访问。
3.调用方法,根据指针名找到对象,根据对象的isa指针找到类,再调用类中的方法。
nil 与NULL
1.null
只能作为指针变量的值,代表这个指针不指向内存中任何空间。
NULL等价于0
2.nil
只能作为指针变量的值,代表这个指针变量不指向内存中的任何空间。
nil等价于0
NULL 和 nil 是一样的
3.使用建议
C的指针用NULL
OC的类指针用nil
4.如果1个类指针的值为nil. 代表这个指针不指向任何对象
用空类指针访问对象的属性,会报错
访问对象的方法不会报错,但方法不会执行 没有任何反应
方法和函数
相同点:被封装起来的一段相对独立功能的代码,函数或方法只要被调用,那么封装在其中的代码就会被自动执行。
不同点:
1.语法不同
2.定义的位置不同
函数不能在另一个函数的内部定义
3.函数可以直接调用,方法必须通过对象调用
4.方法是属于类的,函数是孤立的
注意:
1.@interface是类的声明,@implementation 是类的实现 二者不能互相嵌套
2.类必须先声明后实现,但实现可以放在类的使用的后面
3.类的声明和实现必须都要有,就算没有方法,类的实现也是比不可少的
4.声明类的时候,类的声明和实现必须要同时存在,特殊情况下可以只有实现 ,没有声明
5.属性名一定要以下划线开头,规范化
类名首字母大写
6.类的属性初始化的时候不能赋值
7.OC的方法只能通过对象调用
8.方法只有声明没有实现
方法只有声明没有实现,编辑器警告
如果指针指向的对象 有方法无声明 调用这个方法时就会报错
类的本质
本质:是自定义的一个数据类型
数据类型:是在内存中开辟空间的一个模板
对象作为参数
1.当对象作为方法的参数的时候,参数的类型是一个类指针
2.调用方法的时候,如果方法的参数是1个对象,那么实参也是一个对象
3.当对象作为方法的参数的时候,是按地址传递,所以在方法内部通过形参去改变形参指向的对象属性时,会影响实参变量的对象值
4.如果方法的返回值是一个对象,那么返回值类型应该写类指针