1.内存泄露
指的是1个对象没有被及时的回收.在该回收的时候而没有被回收
一直驻留在内存中,直到程序结束的时候才回收.
2.单个对象的内存泄露的情况
1).有对象的创建,而没有对应的relase
2). retain的次数和relase的次数不匹配.
3).在不适当的时候,为指针赋值为nil(指针指向的内存空间未被回收)。
4).在方法中为传入的对象进行不适当的retain。
3.如何保证单个对象可以被回收
1).有对象的创建就必须要匹配1个relase
2). retain次数和release次数一定要匹配.
3).只有在指针称为野指针的时候才赋值为nil
4).在方法中布不要随意的为传入的对象retain.
4.当属性是1个OC对象的时候. setter方法的写法
将传进来的对象赋值给当前对象的属性,代表传入的对象多了1个人使用,所以我们应该先为这个传入的对象发送1条retain消息再赋值.
当当前对象销毁的时候.代表属性指向的对象少1个人使用.就应该在dealloc中relase
代码写法:
- (void)setCar:(Car *)car
{
_car = [car retain];
}
- (void)dealloc
{
[_car release];
[super dealloc];
}
5.当属性是1个OC对象的时候,setter方法照着上面那样写,其实还是有Bug的.
当为对象的这个属性多次赋值的时候.就会发生内存泄露.
发生泄露的原因:当为属性赋值的时候,代表旧对象少1个人用.新对象多1个人使用.
应该relase旧的 retain新的
- (void)setCar:(Car *)car
{
[_car release];
_car = [car retain];
}
6. 在MRC的开发模式下.1个类的属性如果是1个OC对象类型的.那么这个属性的setter方法就应该按照下面的格式写.
- (void)setCar:(Car *)car
{
if(_car != car)
{
[_car release];
_car = [car retain];
}
}
还要重写dealloc方法.
- (void)dealloc
{
[_car release];
[super delloc];
}
如果属性的类型不是OC对象类型的.不需要像上面那样写. 还是像之前那样写就OK了.
7. @property
1). 作用
a. 自动生成私有属性.
b. 自动生成这个属性的getter setter方法的声明.
c. 自动生成这个属性的getter setter方法的实现.
特别播报:
生成的setter方法的实现中,无论是什么类型的,都是直接赋值.
8. @property参数.
1). @property可以带参数的.
@property(参数1,参数2,参数3......)数据类型 名称;
2). 介绍一下@property的四组参数.
a. 与多线程相关的两个参数.
atomic、nonatomic.
b. 与生成的setter方法的实现相关的参数.
assign、retain.
c. 与生成只读、读写相关的参数
readonly readwrite
d. 是与生成的getter setter方法名字相关的参数.
getter setter
9. 介绍与多线程相关的参数.
atomic: 默认值. 如果写atomic,这个时候生成的setter方法的代码就会被加上一把线程安全锁.
特点: 安全、效率低下.
nonatomic: 如果写nonatomic 这个时候生成的setter方法的代码就不会加线程安全锁.
特点: 不安全,但是效率高.
建议: 要效率. 选择使用nonatomic 在没有讲解多线程的知识以前 统统使用nonatomic
10. 与生成的setter方法的实现相关的参数.
assign: 默认值 生成的setter方法的实现就是直接赋值.
retain: 生成的setter方法的实现就是标准的MRC内存管理代码.
也就是. 先判断新旧对象是否为同1个对象 如果不是 release旧的 retain新的.
当属性的类型是OC对象类型的时候,那么就使用retain
当属性的类型是非OC对象的时候,使用assign.
千万注意:
retain参数.只是生成标准的setter方法为标准的MRC内存管理代码 不会自动的再dealloc中生成relase的代码.
所以, 我们还要自己手动的在dealloc中release
11. 与生成只读、读写的封装.
readwrite: 默认值.代表同时生成getter setter
readonly: 只会生成getter 不会生成setter
12. 生成getter、setter方法名称相关的参数.
默认情况下.@property生成的getter setter方法的名字都是最标准的名字.
其实我们可以通过参数来指定@property生成的方法的名字.
getter = getter方法名字 用来指定@property生成的getter方法的名字.
setter = setter方法名字.用来指定@property生成的setter方法的名字. 注意.setter方法是带参数的 所以要加1个冒号.
记住:如果使用getter setter修改了生成的方法的名字.
在使用点语法的时候.编译器会转换为调用修改后的名字的代码.
修改生成的getter setter方法名字. 因为默认情况下生成的方法的名字已经是最标准的名字了.
所以.一般情况下不要去改.
1). 无论什么情况都不要改setter方法的名字. 因为默认情况下生成的名字就已经是最标准的了.
2). 什么时候修改getter方法的名字.当属性的类型是1个BOOL类型的时候.就修改这个getter的名字以is开头 提高代码的阅读性.
------总结-------
1. 与多线程相关的参数: 用nonatomic
2. 与生成的setter方法实现相关的参数
属性的类型是OC对象的时候 使用retain
属性的类型是非OC对象的时候 使用assign
3. 只读 读写.
如果你希望生成的封装是只读封装 那么就使用readonly
如果希望读写封装 readwrite
4. 1). 无论什么情况都不要改setter方法的名字. 因为默认情况下生成的名字就已经是最标准的了.
2). 什么时候修改getter方法的名字.当属性的类型是1个BOOL类型的时候.就修改这个getter的名字以is开头 提高代码的阅读性.
------使用参数注意-----
1. 同1组参数只能使用1个.
getter setter可以同时使用.
2. 参数的顺序可以随意.