1.@class
使用場景:對於循環依賴關系來說,比方A類引用B類,同時B類也引用A類;
可以看出Person和Card互相引用,此時如果使用#import編譯報錯!因此當使用@class在兩個類中相互聲明,編譯不會報錯!
用法:使用 @class 類名; 就可以引用一個類,說明一下它是一個類
@class和#import的區別:
#import方式會包含被引用類的所有信息,包括被引用類的變量和方法;@class方式只是告訴編譯器在A.h文件中 B *b 只是類的聲明,具體這個類裡有什麼信息,這裡不需要知道,等實現文件中真正要用到時,才會真正去查看B類中信息
如果有上百個頭文件都#import了同一個文件,或者這些文件依次被#improt,那麼一旦最開始的頭文件稍有改動,後面引用到這個文件的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方式就不會出現這種問題了
在.m實現文件中,如果需要引用到被引用類的實體變量或者方法時,還需要使用#import方式引入被引用類
2.循環retain
比如A對象retain了B對象,B對象retain了A對象
這樣會導致A對象和B對象永遠無法釋放
3.解決方法
當兩端互相引用時,應該一端用retain、一端用assign 模擬代碼如下:
復制代碼
復制代碼
/**
需求:人擁有身份證,而身份證上顯示人的信息,
設計:分別設計Person類和Card類模擬
注意:兩個類循環引用因此設置Card一端為assign
*/
復制代碼
/********************************* Person.h *************************************/
#import <Foundation/Foundation.h>
@class Card;
@interface Person : NSObject
@property (nonatomic,retain) Card *card;
@end
/********************************* Person.m *************************************/
#import "Person.h"
#import "Card.h"
@implementation Person
- (void)dealloc
{
[_card release];
NSLog(@"Person對象被回收了");
[super dealloc];
}
@end
/********************************* Card.h *************************************/
#import <Foundation/Foundation.h>
@class Person;
@interface Card : NSObject
// 雖然Person是類對象 但為了解決互相retain的問題 將Car的這一端的person設置成為assign
@property (nonatomic,assign) Person *person;
@end
/********************************* Card.m *************************************/
#import "Card.h"
#import "Person.h"
@implementation Card
- (void)dealloc
{
NSLog(@"Card對象被回收");
[super dealloc];
}
@end
/********************************* main.m *************************************/
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Card.h"
int main(int argc, const char * argv[])
{
Person *person = [[Person alloc] init];
Card *card = [[Card alloc] init];
// 人擁有身份證
person.card = card; // 執行後card的引用計數 = 2
// 身份證上顯示的人的信息 Car中person中assign person引用計數 = 1
card.person = person;
// card計數-1
[card release];
// persong引用計數 = 0 person對象要被回收了 調用 person.dealloc 方法
[person release];
return 0;