------Java培训、Android培训、iOS培训、.Net培训--------
一、@class的使用方法
1、使用
【@import】会把引用的头文件整个拷贝到@import的使用处
如果该头文件改变了,那么所有引用它的文件都需要重新编译,导致效率非常低
【@class的使用】
格式:@class XXX;
【含义】告诉编译器,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....