黑马程序员——ios基础---Objective-C:构造方法、@property、MRC
来源:互联网 发布:cad网络电子版图纸 编辑:程序博客网 时间:2024/06/14 23:10
一、@property等
1、点语法:对象名.成员变量名 (点语法不是访问成员变量,而是方法的调用)
它是一个编译器特性
点语法作用:可以替换传统的get和set方法的调用
点语法前提:*首先得先有 get和set方法
点语法实质: 调用get和set方法
如果点语法出现在 = 的左边,表示设置值,相当于调用了set方法
// 设置age的值
stu.age = 10; // 等价于[stusetAge:10];
如果点语法出现在 = 的右边,表示获取值,相当于调用了get方法
int age= stu.age; // 等价于int age = [stu age];
2、@property:
1)@property 在Xcode4.4之前的使用方法
(1)只是用@property作为方法的声明
格式:@property int age; 表示帮我们生成一个get和set age的方法声明
{
int age;
NSString *name;
}
@property int age;
-(void)setAge:(int) age;
-(int)age;
//手工实现 get和set方法
-(void)setAge:(int) age{
self->age = age;
}
-(int)age{
return age;
}
@property NSString *name;
-(void)setName:(NSString*) name;
-(NSString*)name;
(2)@synthesize 关键字
@synthesize 变量名;
自动帮我们实现对应的get和set方法的实现
@synthesize age;
@synthesize 相当于帮我们实现了下面的方法
-(void)setAge:(int) age{
self->age = age;
}
-(int)age{
return age;
}
(3)@synthesize name =_b;
{
NSString *name;
NSString *_b;
}
-(void)setName:(NSString *) name{
_b = name;
}
-(NSString *)name{
return _b;
}
@synthesize name = _b; //相当于操作_b的值
注意:在4.4之前,@property和@synthesize成对出现
2)@property 在Xcode4.4之后(@property增强)
增强使用:
@property int score;
1).h文件中 帮我们声明 setScore(setter) 和 score(getter)方法
2).m 中帮我们生成 _score的私有变量(在外部不能访问,不能被子类继承)
3).m 中帮我们实现 get和set方法
3、id类型
id是动态类型,程序只有在运行时才能确定它的具体类型。是指向哪个对象的。
id是一种通用的对象类型,它可以用来存储属于任何类的对象也可以理解为万能指针
注意 在id的定义中,已经包好了*号。id指针只能指向os的对象。
id 类型的定义
Typedef struct objc object{
Class isa;
} *id;
局限性:调用一个不存在的方法,编译器会马上报错。
iOS5之后推出了instancetype类型
instancetype和id的异同
1) 相同点都可以作为方法的返回类型
2) 不同点
1,instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
2,instancetype只能作为返回值,不能像id那样作为参数,
id类型应用场景 :
//动物类
Animal *animal = [Animal new]; //狗的类,狗继承自动物
Dog *dog = [Dog new]; //猫的类,猫继承自动物
Cat *cat = [Cat new]; //定义id类型
id obj = cat; //id obj = dog;
[objrun];
4、动态类型和静态类型:
动态类型:程序在运行的时候,才能确定对象属于什么类型
静态类型:程序编译的时候,就确定了对象的类型
动态类型的体现: 多态,父类指针可以指向子类对象
NSObject 是所有类的基类
NSObject*obj = [Dog new];
obj =[Person new];
父类调用子类特有的方法
[(Person*)obj eat];
//id类型,id类型又被称为 万能指针。
id obj; //运行时检查
obj = [Carnew];
[(Car*)objstop];
1)对象所属关系判断
isKindofClass,对象是否是指定类或者子类的实例对象,
isMemberOfClass, 对象是否是指定类的实例对象
isSubclassOfClass ,类是否是另外一个类的子类
二、构造方法:
1)构造方法的调用:
完整的创建一个可用的对象:Person *p=[Person new];
new方法的内部会分别调用两个方法来完成3件事情:
(1)使用alloc方法来分配存储空间(返回分配的对象);
(2)使用init方法来对对象进行初始化。
(3)返回对象的内存首地址 。
可以把new方法拆开如下:
(1).调用类方法+alloc分配存储空间,返回未经初始化的对象
Person *p1=[Person alloc];
(2).调用对象方法-init进行初始化,返回对象本身
Person *p2=[p1 init];
(3).以上两个过程整合为一句:
Person*p=[[Person alloc] init];
说明:
(1)init方法就是构造方法,是用来初始化对象的方法,称为构造初始化。注意这是一个对象方法,以减号开头。
向某个类发送init消息的结果,构造初始化该类的所有成员变量,默认情况对象为nil,数值类型的为0.
(2) alloc
向某个类发送alloc消息的结果 ,为该类分配内存(对象的内存地址已经有了),以存放该类的全部实例变量 。
注意
一个刚刚分配的对象并不能立即使用 ,
需要先初始化该对象,然后才能使用它 ,
但由于未进行初始化, 随后可能出现一些不可预测的行为.
2、自定义构造方法
1)自定义构造方法的规范
(1)一定是对象方法,以减号开头
(2)返回值一般是id类型
(3)方法名一般以initWith开头
2)自定义构造方法的使用注意
(1)自己做自己的事情
(2)父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性
三、 MRC
1. 内存管理概念理解 :
由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,单个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送MemoryWarning消息。收到此消息后,需要回收一些不需要再 继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会崩溃
内存管理的范围:
主要是对继承了NSObject的对象进行管理。基本数据类型是没有内存管理的。
对象类型是程序运行过程中动态分配的,存储在堆区;
内存管理主要是对 堆区中的对象的内存管理。
2. 引用计数器 :
对象的引用计数器
每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数,即现在有多少东西在使用这个对象。对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。 。
关闭ARC的方法
选中项目 -> 选中Build Settings -> 选中All -> 搜索 Automatic Reference Counting-> 修改为No
3. dealloc方法
1)当对象即将被销毁, 系统自动给对象发送一条dealloc消息
2)因此, 从dealloc方法有没有被调用, 就可以判断出对象是否被销毁
3)重写了dealloc方法, 必须调用[super dealloc], 并且放在最后面调用
4)不要自己直接调用dealloc方法
4. 野指针\空指针\僵尸对象
僵尸对象: 已经被销毁的对象(不能再使用的对象)
野指针: 指向僵尸对象(不可用内存)的指针
空指针: 没有指向存储空间的指针(里面存的是nil, 也就是0)
注意: 给空指针发消息是没有任何反应的, 不会