栈、堆、BSS、数据段、代码段是什么?架构
栈(stack):又称做堆栈,用来存储程序的局部变量(但不包括static声明的变量,static修饰的数据存放于数据段中)。除此以外,在函数被调用时,栈用来传递参数和返回值。函数
堆(heap):用于存储程序运行中被动态分配的内存段,它的大小并不固定,可动态的扩张和缩减。操做函数(malloc/free)指针
BSS段(bss segment):一般用来存储程序中未被初始化的全局变量和静态变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段输入静态内存分配code
数据段(data segment):一般用来存储程序中已被初始化的全局变量和静态变量和字符串的一块内存区域对象
代码段(code segment):一般是指用来存储程序可执行代码的一块内存区域。这部分区域的大小在程序运行前就已经肯定,而且内存区域一般属于只读,某些架构也容许代码段为可写,即容许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量。内存
Person *p1 = [Person new]
看这行代码,先来看几个注意点:字符串
new底层作的事情:it
在堆内存中申请1块合适大小的空间io
在这块内存上根据类模版建立对象。类模版中定义了什么属性就依次把这些属性声明在对象中;对象中还存在一个属性叫作isa,是一个指针,指向对象所属的类在代码段中地址import
初始化对象的属性。这里初始化有几个原则:a、若是属性的数据类型是基本数据类型则赋值为0;b、若是属性的数据类型是C语言的指针类型则赋值为NULL;c、若是属性的数据类型为OC的指针类型则赋值为nil。
返回堆空间上对象的地址
注意
对象只有属性,没有方法。包括类自己的属性和一个指向代码段中的类isa指针
如何访问对象的属性?指针名->属性名;本质:根据指针名找到指针指向的对象,再根据属性名查找来访问对象的属性值
如何调用方法?[指针名 方法];本质:根据指针名找到指针指向的对象,再发现对象须要调用方法,再经过对象的isa指针找到代码段中的类,再调用类里面方法
为何不把方法存储在对象中?
由于以类为模版建立的对象只有属性可能不相同,而方法相同,若是堆区的对象里面也保存方法的话就会很重复,浪费了堆空间,所以将方法存储与代码段
因此一个类建立的n个对象的isa指针的地址值都相同,都指向代码段中的类地址
作个小实验
#import <Foundation/Foundation.h> @interface Person : NSObject{ @public int _age; NSString *_name; int *p; } -(void)sayHi; @end @implementation Person -(void)sayHi{ NSLog(@"Hi, %@",_name); } @end int main(int argc, const char * argv[]) { Person *p1 = [Person new]; Person *p2 = [Person new]; Person *p3 = [Person new]; p1->_age = 20; p2->_age = 20; [p1 sayHi]; [p2 sayHi]; [p3 sayHi]; return 0; }
Person *p1 = [Person new];
这句代码在内存分配原理以下图所示
结论
能够 看到Person类的3个对象p一、p二、p3的isa的值相同。