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