IOS学习第24天
@class
1.两个类A和B,如果互相#import对方头文件,会造成死循环
2.解决方式:
在其中的一方,不要用#import <xxx.h>来引入对方的头文件,用@class 对方的类名
#import "B.h"
@interface A : NSObject
@end
//#import "A.h"
@class A;//告诉编译器 有名字叫做A这么一个类
@interface B : NSObject
@end
#import "A.h"
@implementation B
{
}
最后:
#import 和@class 的区别
1>归属的类型不同
#import 是预处理指令,在编译之前会进行内容替换
@class 类名 这是一句OC代码
2>作用不同
#import 拷贝包含的头文件,替换到写包含指令的这一行
@class 类名 :仅仅是告诉编译器 有这么一个类
```
###循环retain
1.什么是循环retain?
A类中有一个属性是B类的对象
B类中有一个属性是A类的对象
这时候如果A类中 B类的对象用retain参数
B类中的 A类对象也用retain参数
那么就会造成循环retain,导致内存泄漏
2.解决方法:
一段用retain 另外一端用assign
注意:用assign的那一端 在dealloc中 不需要再调用release
###自动释放池的使用
1.自动释放池是什么?
用来存放对象的一个池子
存储在自动释放池中的对象,当自动释放出销毁的时候,会向存储池子中的”所有对象”发送一条release消息
2.如果把一个对象放入自动释放池中?
只要在自动释放池的范围内 调用对象的autorelease方法,就可以把对象放入池子中了
2.自动释放池的好处
唯一好处:可以省略创建对象以后要匹配的那个release代码
```
- 使用自动释放池的七大注意
1). 只有在自动释放池中调用了对象的autorelease方法,这个对象才会被存储到这个自动释放池之中.
如果只是将对象的创建代码写在自动释放之中,而没有调用对象的autorelease方法.是不会将这个对象存储到这个自动释放池之中的.
2). 对象的创建可以在自动释放池的外面,在自动释放池之中,调用对象的autorelease方法,就可以将这个对象存储到这个自动释放池之中.
将1个对象存储到自动释放池中,最重要的步骤
调用对象的autorelease方法,这句代码一定要放在池子中.
3). 当自动释放池结束的时候.仅仅是对存储在自动释放池中的对象发送1条release消息 而不是销毁对象.
4). 如果在自动释放池中,调用同1个对象的autorelease方法多次.就会将对象存储多次到自动释放池之中.
在自动释放池结束的时候.会为对象发送多条release消息.那么这个时候就会出现僵尸对象错误.
所以,1个自动释放池之中,只autorelease1次,只将这个对象放1次, 否则就会出现僵尸对象错误.
5). 如果在自动释放池中,调用了存储到自动释放中的对象的release方法.
在自动释放池结束的时候,还会再调用对象的release方法.
这个时候就有有可能会造成野指针操作.
也可以调用存储在自动释放池中的对象的retain方法.
6). 将对象存储到自动释放池,并不会使对象的引用计数器+1
所以其好处就是:创建对象将对象存储在自动释放池,就不需要在写个release了.
7). 自动释放池可以嵌套.
调用对象的autorelease方法,会讲对象加入到当前自动释放池之中
只有在当前自动释放池结束的时候才会像对象发送release消息.
- 自动释放池的规范
如果使用类方法创建一个对象,要求必须这个对象在方法中已经被autorelease过了
ARC
**弱指针在对象被回收后自动设置为nil
- ARC机制的概述
1.什么是ARC?
自动引用计数器管理:
编译器会在适当,适当地点插入和内存管理有关系(retain release autorelease,dealoc)
2.ARC下对象是怎么回收
本质上:不管在MRC 还是ARC,对象的引用计数器的值为0的时候回收
3.表像上
一个对象 如果有没任何的强指针指向的时候 他会被系统立即回收
4.强指针 和 若指针
强指针:指针如果前面有__strong修饰指针[默认]
若指针:指针如果前面有__weak修饰指针
在ARC下 强指针 和若指针有什么区别?没有任何区别
是系统会根据 有没有强指针指向对象 来判断对象是否可以被回收
- @property参数strong与weak
1.@property参数strong与weak
作用:@property 自动生成的私有属性 到底是强指针 还是 弱指针
"@property (strong/weak) NSString * name;
strong:生成的私有属性是强指针
weak:生成的私有属性是弱指针
在ARC机制下 setter方法的实现 就是直接赋值 不需要做任何事情
在ARC下 不能用retain,因为retain是指生成的setter方法的实现 中 是标准的内存管理代码
一般来说在MRC下用retain参数 ---> ARC下就用strong
一般来说在MRC下用assign参数--->ARC下就用assign
- ARC机制下的循环应用
1.什么是循环引用
当对象A中有对象B作为属性
而且 对象B中有对象A作为属性
如果这两个属性 都是用__strong修饰那么就会形成循环引用
就会导致两个对象都不能回收
2.例题:
人类Person:
{
电脑属性;
}
电脑类Computer:
{
人属性(拥有者);
}
3.人对象中拥有电脑对象属性,电脑对象中拥有人对象属性.那么会导致电脑和人对象都不能释放.
"解决方案:
一端用strong 一端用weak
```
* property参数总结
与多线程相关的参数.
atomic:
nonatomic:
这两个参数,无论在MRC还是ARC下都可以使用. 使用nonatomicretain: 只能使用在MRC模式下.
在MRC模式下: 当属性的类型是OC对象的时候,绝大多数场景之下使用retain.
assign: 可以使用在ARC和MRC模式之下.
在ARC下: 当属性的类型是非OC对象的时候,一律使用assign.
在MRC模式下: 当属性的类型是非OC对象的时候,一律使用assign.
在MRC模式下.出现循环引用的时候. 1边使用assign 1边使用retain.
strong: 只能使用在ARC模式下.当属性的类型是OC对象的时候,绝大多数场景之下使用strong.
weak:只能使用在ARC模式下 当出现循环引用的时候.1边使用strong 1边使用weak.getter setter 修改方法名字.
无论是ARC还是MRC都可以通过他们修改方法的名字.readonly
readwrite.
无论MRC还是ARC都可以使用
终极写法
MRC:
@property (nonatomic,assgin(非OC对象)/retain(OC对象)) 类型 属性名称
大部分情况 只要是OC对象 用retain
当出现 循环retain时候
一端用retain 另外一端用assign
ARC:
@property (nonatomic,assign(非OC对象)/weak/strong) 类型 属性名称
大部分情况只要是OC对象就是strong
当出现循环引用的时候 一端用weak 一端用strong
* MRC与ARC的兼容
** 选中MRC文件,双击后输入 -fno-objc-arc **
###分类
* 分类的简单使用
1.什么是分类
当一个类包含了非常的多的属于不同范畴的方法的时候,我们通常将这个类用多个文件来实现,其中有一个类叫主/本类,剩余的叫分类
2.有了分类之后
一个类 = 所有分类 + 本类
3.如何添加分类:
newFile–> 选中OC File –>选择category
—>填写分类名,本类名
4.分类的声明
@interface 本类名 (分类名)
@end
@implementation 本类名 (分类名)
@end
5.如何使用分类
只要在使用的时候导入分类即可
“`