一、 对象在内存中的存储
内存中的五大区域
栈 存储局部变量
堆 程度员手动申请的字节看空间 malloc calloc realloc函数
BSS段 存储未被初始化的全局变量, 静态变量
数据段(常量区) 存储已被初始化的全局、静态变量、常量数据
代码段 存储代码 存储代码程序类加载
a. 在创建对象的时候 肯定需要访问类
b. 声明1个类的时候指针变量也会访问类
类加载: 在程序运行期间,当某个类第1次被访问的时候就会把类加载到代码段
只有类在第1次被访问的时候,才会做类加载. 一旦类被加载到代码段后,直到程序结束的时候才会被释放-
对象在内存中究竟是如何存储的
假设下面这个写在函数中
Person *p1 = [Person new];- Person *p1 : 会在栈内存中申请1空间,在栈内存中声明1个Person类型的指针变量,
p1是指针变量,只能存储地址 - new做的事情:
a. 在堆内存中申请1块合适大小的空间
b. 在这个控件中根据类的模板创建对象
依次声明属性,对象还有额外的一个属性,叫isa是一个指针。
isa指向所属的类在代码段当中的地址.
c. 初始化对象的属性
如果属性的类型是基本数据类型,就赋值为0;
如果属性的类型是C语言的指针类型,就赋值为NULL;
如果属性的类型是OC语言的指针类型,就赋值为nil;
d. 返回对象的地址 - 注意
a. 对象当中只有属性,而没有方法, 自己类的属性外加1个isa指针指向代码段中的类
b. 如何访问对象的属性
指针名->属性名;
根据指针 找到指针指向的对象 再找到对象中的属性来访问
c. 如何调用方法
[指针名 方法名];
先根据指针名找到对象,对象发现要调用方法 再根据对象的isa指针找到类,然后调用类里的方法
- Person *p1 : 会在栈内存中申请1空间,在栈内存中声明1个Person类型的指针变量,
为什么不把方法存储在方法之中
因为每个对象的方法实现代码都是一模一样的,所以只保存一份来节省空间对象属性的默认值
如果我们创建一个对象,每一为对象的属性赋值,这个对象是有值的。
如果属性的类型是基本数据类型,就赋值为0;
如果属性的类型是C语言的指针类型,就赋值为NULL;
如果属性的类型是OC语言的指针类型,就赋值为nil;-
NULL与nil
1). NULL
只能可以作为指针变量的值,如果1个指针变量的值是NULL代表这个指针不指向内存中的任何一块空间,NULL其实等价于0.是一个宏
#define NULL ((void *)0)
2). nil
只能作为指针变量的值. 代表这个指针不指向内存中的任何空间.
nil也等价于0 也是一个宏所以NULL和nil是一样的
3). 使用建议
a. C指针用NULL值
int *p = NULL;
b. OC的类指针用nil
Person *p = nil;4). 如果1个类指针的值为nil,代表这个指针不指向任何对象
Person *p = nil;
不能向它的属性赋值, 对象的方法不会执行. 同类型的指针变量之间是可以相互赋值的
-
分组导航标记
导航栏中的main.m后的No Selection点击选择方法或类- #pragma mark 分组名
在@interface和@implementation上方添加 - #pragma mark -
在导航条对应的位置显示一条水平分割线 - #pragma mark - 分组名
在导航条对应的位置产生一条水平分割线,再产生分组名
- #pragma mark 分组名
-
函数和方法对比
- 在C中学习的叫做函数
void test(){} - 在OC类当中写的叫方法
- (void)sayHi;
- 相同点:
都是用来封装代码,表示一个相对独立的功能 - 不同点:
a. 语法不同.
b. 定义的位置不一样
OC方法的声明只能写在@interface的大括弧外面,实现只能写在@implementation.
函数除了函数的内部和@interface大括弧之中,其他地方都可以写
c. 调用的方式不同:
函数可以直接调用, 方法必须要创建之后调用
d. 方法是属于类的, 函数是对立的
- 在C中学习的叫做函数
最容易犯的错
1). @interface与@implementation不能相互嵌套
2). 类必须要先声明
3). 类的声明和实现必须都有要
4). 类的声明必须要放在使用类之前,实现可以放在其后
5). 声明类的时候,声明和实现必须要同时存在.
特殊情况: 可以只有实现,没有声明. 但不可这么写
6). 属性名一定要以下划线开头, 类名首字母要大写
7). 属性不允许声明的时候赋值
8). OC方法必须要创建对象通过对象名来调用
9). 方法不能只声明不实现
unrecognized selector sent to instance 0x100420510
方法不存在或者没有实现
二、多文件开发
多文件开发
把1个类写在一个模块当中, 而一个模块至少两个文件
.h 头文件
写类的声明
.m 实现文件
写类的实现简洁方式
NewFile->Cocoa Class即可对象和方法
对象作为方法的参数, 对象作为方法的返回值
1). 类的本质是我们自定义的数据类型
什么是数据类型: 是在内存中开辟空间的模板
2). - (void)test:(Dog *)dog;
3). 当对象作为方法参数传递的时候,是地址传递.-
对象作为方法的返回值
- (Dog *)product;
-
对象作为类的属性
1). 一个Target中的类无法直接在另一个Target中使用
2). 属性的本质是变量@interface Person : NSObject { Dog *dog; } @end
-
本类对象作为本类方法的参数
@interface Dog : NSObject{ int _age; } - (BOOL) compare: (Dog *)dog; @end @implementation Dog - (BOOL) compare: (Dog *)dog{ return _age > dog->_age; } @end