黑马程序员----Objective-C学习笔记之@class与循环retain问题
来源:互联网 发布:电子小报制作软件 编辑:程序博客网 时间:2024/06/08 18:04
一、@class的使用方法
1、使用
【@import】会把引用的头文件整个拷贝到@import的使用处
如果该头文件改变了,那么所有引用它的文件都需要重新编译,导致效率非常低
【@class的使用】
格式:@classXXX;
【含义】告诉编译器,XXX是一个类,至于类有哪些方法和属性,此处不去检测。
【好处】如果XXX文件内容发生了改变,而不需要重新编译
【缺点】因为无法检测到引入类的方法和属性,因此也无法访问。
【解决方法】因为编译时先编译.h头文件,因此在.h头文件中使用@class告知有要引入的类,.m文件是在运行时编译,因此可以在.m文件中使用#import指定的头文件,这样只有程序运行的时候才去检查,然后重新编译,可以极大地提高效率。
【注意】
1).h @class类名;
2).m #import类名;
2、@class可以解决循环引入问题
例如:
有A、B两个类,如果在A类头文件中使用#import引入了B,又在B类头文件中使用#import引入了A,这样在就会报错。
【解决方案】在两个类的头文件中使用@class引入对方的类名
二、循环retain问题
1、循环retain的问题
会导致两个对象的内存泄露
【解决方案】
1)让某个对象多释放一次,(注意顺序)
2)【推荐方法】一端使用assign一端使用retain
例子:
【人有一条狗,狗有一个主人】
【Person.h文件】
#import <Foundation/Foundation.h>@class Dog; @interface Person : NSObject{ //人拥有一条狗,使用的是retain Dog *_dog;}@property(nonatomic,retain) Dog *dog;@end
【Person.m文件】
#import "Person.h"#import "Dog.h"@implementation Person-(void)dealloc{ //人死前先把狗放了 [_dog release]; NSLog(@"This person dead...."); [super dealloc];}@end
【Dog.h文件】
#import <Foundation/Foundation.h>@class Person;@interface Dog : NSObject{ //狗有一个主人,使用retain Person *_p;}@property(nonatomic,retain) Person *p;@end
【Dog.m文件】
#import "Dog.h"#import "Person.h"@implementation Dog-(void)dealloc{ //狗跑之前先把主人咬死 [_p release]; NSLog(@"The dog is gone...."); [super dealloc];}@end
【main.m文件】
#import <Foundation/Foundation.h>#import "Person.h"#import "Dog.h" int main(int argc, const char * argv[]){ @autoreleasepool { //实例化一个person对象 Person *p = [Person new]; //p的计数器值 1 Dog *dog = [Dog new];//dog的计数器值 1 p.dog = dog;//dog的计数器值 2 dog.p = p;//p的计数器值 2 [dog release];//dog的计数器值 1 [p release];//p的计数器值 1 } return 0;}
【结果分析】
最后dog和p的计数器值都为1.最后两个对象的堆区内存都没有被释放,导致了内存泄露。
【误区】
一开始我认为在delloc方法中,两个对象不都把拥有的对象给release掉了么?怎么也想不明白为什么最后计数器值都为1。最后终于明白了,只要记住一点【delloc只有在一个对象的计数器值为0的时候由系统自动调用的】就行了。这样是不是就明白了呢?
【解决方法1】任何一个对象多释放一次,不过这样需要注意顺序,具体需要计算他们的计数器值
[dog release];//dog的计数器值 1 [p release];//p的计数器值 1<span style="white-space:pre"></span> [p release];//p的计数器值 1
【解决方法2:墙裂推荐】一端使用assign一端使用retain
只要把
Dog.h文件中的属性改为
@property(nonatomic,assign) Person *p;
Dog.m文件中的方法改为
-(void)dealloc{ NSLog(@"The dog is gone...."); [super dealloc];}
此时打印结果:
2015-10-06 15:31:53.418 MRCDemo[1967:303] The god isgone....
2015-10-06 15:31:53.420 MRCDemo[1967:303] This persondead....
- 黑马程序员----Objective-C学习笔记之@class与循环retain问题
- 黑马程序员---内存管理之循环retain和@class
- objective-c循环retain和@class
- 黑马程序员--OC内存管理之循环retain问题
- 【黑马程序员】Objective-C语言学习笔记之小知识点
- 黑马程序员---Objective-C学习笔记之二
- 黑马程序员---Objective-C 学习笔记之三
- 黑马程序员---Objective-C Foundation框架学习笔记之二
- 黑马程序员----Objective-C学习笔记之动态类型检测
- 黑马程序员----Objective-C学习笔记之构造方法
- 黑马程序员----Objective-C学习笔记之@property参数
- 黑马程序员----Objective-C学习笔记之autorelease基本使用
- 黑马程序员----Objective-C学习笔记之NSString类的内存管理问题
- 黑马程序员---Objective-C学习笔记之一
- 黑马程序员------Objective-C-------#include,#import与@class的讨论
- 黑马程序员——Objective-C程序设计(第4版)学习笔记之05-循环结构——黑马 IOS 技术博客
- 黑马程序员----Objective-C学习笔记之OC基础练习笔记
- 黑马程序员-------c语言学习笔记之数组与字符串
- myisam 与 innodb在联合索引查询上的一些区别
- C/C++中指针所能指向的地址范围
- hdu 5112 (2014北京 水)
- Android源码开发之获取当前时间的时分秒
- 交换两个数的值,不借助第三方变量.
- 黑马程序员----Objective-C学习笔记之@class与循环retain问题
- 链接获取Json字符串后遍历
- 学习网站
- HDU 1950 Bridging signals(LIS)
- 百度2016研发工程师在线编程题
- android studio 编译出错 非法字符 未结束的字符
- ubuntu15.04手动安装MySQL5.6.27数据库
- hdu 5113(2014北京—搜索+剪枝)
- Java面向对象(一)