黑马程序员----Objective-C学习笔记之@class与循环retain问题

来源:互联网 发布:电子小报制作软件 编辑:程序博客网 时间:2024/06/08 18:04
------Java培训、Android培训、iOS培训、.Net培训--------

一、@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....


0 0
原创粉丝点击