一、内存中的五大区域
- 栈 存储局部变量
- 堆 程序员手动申请的字节空间
- BSS段 存储未被初始化的全局变量、静态变量
- 数据段(常量区) 存储已被初始化的全局、静态变量、常量数据
- 代码段 存储代码、存储程序的代码
二、类加载
- 在创建对象的时候,要访问类
- 声明一个类的指针变量会访问类
当程序运行期间,当某个类第一次被访问到的时候,会将这个类存储到内存中的代码段区域,这个过程叫做类加载。只有类第一次被访问的时候才会做类加载,一旦类被加载到代码段后,直到程序结束才会被释放
三、对象在内存中究竟是如何存储的
Person *p1 = [Person new];
- Person *p1; 会在栈内存当中申请一块空间,在栈内存中声明1个Person类型的指针变量p1,p1是1个指针变量,只存储地址
-
[Person new]; 真正在内存中创建对象的代码
new在做的事情
- 在堆内存中申请1块合适大小的空间
- 在这个空间中根据类的模版创建对象
- 类模版中定义了什么属性,就将这些属性一次的生命在对象当中
- 对象中除了自己类中定义的属性,还有另外一个属性叫做 isa 是一个指针 只想对象所属的类在代码段中所存的地址
- 初始化对象的属性,如果是基本数据类型则赋值为0,如果是C语言的指针类型则为NULL,若是OC的类指针类型则赋值为nil
- 返回对象的地址 于是Person *p1 = [Person new]; 将地址赋值给p1
- 对象中只有属性,没有方法,自己累的属性外加1个isa指针指向代码段中的类
- 访问对象的属性 指针名->属性名;
- 调用方法 :[指针名 方法名]根据isa指针找到类中的方法
为什么不把方法存储在对象之中是因为浪费空间
四、nil和NULL
1、NULL 可以作为指针变量的值,如果1个指针变量的值是NULL代表 这个指针不指向内存中的任何1块空间 NULL其实等价于0
2、nil 只能作为指针变量的值,代表指针变量不只想内存当中的任何空间 nil也等价于0 也是一个宏
所以NULL和nil是一样的
3、一般C指针用NULL OC类指针用nil
4、如果一个类指针的值为nil 代表这个指针不指向任何对象。
Person *p1 = nil;
- 此时如果通过p1指针去访问p1指针指向的对象的属性 这个时候会运行报错
- 此时如果通过p1指针去调用对象的方法 运行不会报错
五、分组导航标记
快速寻找标记位置
#pragma mark 分组名
//在导航条对应的位置显示1个标题
#pragma mark -
//在导航条对应位置显示1条水平分割线
六、方法与函数
//函数
void test(){
}
//方法
-(void)sayHi;
七、多文件开发
不把所有类写在同一个.m源文件之中,不利于团队开发
一个类写在一个模块当中,而1个模块至少包含两个文件
- .h 头文件 写类的声明
- .m 实现文件 写类的实现
直接创建Cocoa Class即为 一个模块两个文件
八、对象作为方法的参数
当对象作为方法的参数的时候,参数应该怎么写 参数类型是类指针
-(void)test:(Dog *)dog;
调用方法是 如果方法的参数是一个对象,那么实参时,要是一个符合要求的对象
// Person.h
#import <Foundation/Foundation.h>
#import "Dog.h"
@interface Person : NSObject
{
@public
NSString *_name;
int _age;
}
-(void)sayHi;
-(void)testWith:(Dog *)dog;
@end
// Person.m
#import "Person.h"
@implementation Person
-(void)sayHi
{
NSLog(@"hello");
}
-(void)testWith:(Dog *)dog
{
[dog shoot];
}
@end
//
// Dog.h
#import <Foundation/Foundation.h>
@interface Dog : NSObject
{
@public
NSString *_name;
int _age;
}
-(void)shoot;
@end
//
// Dog.m
#import "Dog.h"
@implementation Dog
-(void)shoot
{
NSLog(@"wangwangwang");
}
@end
//
// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Dog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p1 = [Person new];
Dog *d1 = [Dog new];
[p1 sayHi];
[p1 testWith:(d1)];
}
return 0;
}
//2019-10-08 17:34:07.958000+0800 OC3[4927:715413] hello
//2019-10-08 17:34:07.958980+0800 OC3[4927:715413] wangwangwang