类型如下:
引用类型:reference type
类:class
指针:pointer
块:block
值类型:value type
基础数值类型
结构:struct
枚举:enum
类型装饰
协议:protocol
类别:category
扩展:extension
类:class VS 结构体 struct
类:
接口:@interface 指的是对外可见的部分。
接口文件
@interface Point(类名):NSObject(继承的类)
属性定义 属性:对象的状态
@property int x;
实例方法:方法是行为
-(void)prints;返回值时void的。
@end
比如初始化对象。
Point *p1=[Point alloc] init];//先分配内存,接着初始化。
p1:就叫做对象。
对象的空间分析:
对象:栈上存储的是指针,堆上存储的是真正的对象。
类:是引用类型
指针:存在栈上
实体对象:存在堆上
结构是值类型
值类型,直接存在栈上。
重点 栈(stack)VS 堆(heap)
栈:存储值类型
无ARC(自动引用计数)负担,由系统自动管理,以执行函数为单位(一个函数一个栈,一个栈的大小:根据类型,参数,函数变量等来计算)
空间大小,编译时确定(参数+局部变量)
函数执行时,系统自动分配一个stack栈。
函数执行结束时,系统立即收回stack栈。
函数之间通过拷贝值传递。
具有局部性,大小有限制(一般就几兆),超出会(stack)栈overflow(溢出)。一般不会溢出,除非你写出死循环,超大递归会导致溢出,栈的负担比较小。
堆:存储引用类型对象
分配由程序员手动请求(创建对象的时候)
释放由运行时的ARC机制自动释放(确定时)
函数之间通过拷贝引用(指针)传递。
具有全局性,总体无大小限制(受制于系统内存整体大小),最自由也会最容易出问题,内存泄漏问题。
例子如下:
RPoint.h
#import
@interface RPoint : NSObject
//属性
@property int x;
@property int y;
//打印方法
-(void)prints;
@end
类实现文件
RPoint.m
#import "RPoint.h"
@implementation RPoint
//实现打印方法
-(void)prints{
NSLog(@"[%d,%d]",self.x,self.y);
}
@end
结构体
SPoint.h
typedef struct{
int x;
int y;
}SPoint;
//// main.m
#import#import "RPoint.h"
#import "SPoint.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//初始化对象。手动分配内存
RPoint *rp1=[[RPoint alloc] init];
rp1.x=10;
rp1.y=20;
[rp1 prints];
//再初始化一个对象
RPoint *rp2=rp1;
rp2.x=30;
rp2.y=40;
[rp2 prints];
[rp1 prints];
//指针存在 栈中,会复制一个栈出来,但是堆还是一个。值存在堆中。当rp2和rp1指向的都是同一个堆。所以。rp2改变的时候。rp1也相应改变。
//结构体是值类型。直接存在栈上。
SPoint sp1;
sp1.x=11;
sp1.y=22;
NSLog(@"x=%d,y=%d",sp1.x,sp1.y);
SPoint sp2=sp1;
sp2.x=12;
sp2.y=23;
NSLog(@"x=%d,y=%d",sp2.x,sp2.y);
NSLog(@"x=%d,y=%d",sp1.x,sp1.y);
//结构体,拷贝出来的是一个栈。所以他们的值不是一个。sp2更改后,对sp1没有影响。
}
return 0;
}
网友评论