objective-c循环retain和@class


一、关于@class

1.使用场景

对于循环依赖关系来说,A类引用B类,同时B类也引用A类,这种代码编译会报错。当使用@class在两个类相互声明,就不会报错了。


2.用法概括

使用@class类名,如:@class Card;    //仅仅告诉编译器,Card是一个类。


3.@class的好处

1>能解决循环引用的问题。

2>能提高性能。

4.@class与#import区别

1> #import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息
2>如果有上百个头文件都#import了同一个文件,或者这些文件依次被#improt,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来 讲,使用@class方式就不会出现这种问题了
3>在.m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类


二、循环retain

比如A对象retain了B对象,B对象retain了A对象。

这样就会导致A对象和B对象永远无法释放。

解决方案:

当两端互相引用时,应该一端用retain、一端用assign。


开发中引用一个类的规范:

  1> 在.h中用@class声明类
  2> 在.m中用#import来包含类中所有东西
Card.h
 
#import <Foundation/Foundation.h>


@class Person; // 引用Person类

@interface Card : NSObject

@property (nonatomic, assign) Person *person; //解决方案,这里Person类用assign

@end
Card.m

#import "Card.h" //在.m中用#import来包含类中所有东西
#import "Person.h"

@implementation Card


- (void)dealloc
{
    NSLog(@"Car被销毁了");
    
    // [_person release];   //上面用了assign,没有执行retain,所以这里也不需要release
    
    [super dealloc];
}

@end
Person.h

#import <Foundation/Foundation.h>
#import "Card.h"
// @class仅仅是告诉编译器,Card是一个类
//@class Card;

@interface Person : NSObject

@property (nonatomic, retain) Card *card;

@end
Person.m


#import "Person.h"
#import "Card.h"

@implementation Person

- (void)dealloc
{
    NSLog(@"Person被销毁了");
    [_card release];
    
    [super dealloc];
}

@end


#import <Foundation/Foundation.h>
#import "Card.h"
#import "Person.h"

int main()
{
    // p - 1
    Person *p = [[Person alloc] init];
    // c - 1
    Card *c = [[Card alloc] init];
    
    // c - 2
    p.card = c;
    
    // p - 1
    c.person = p;
    
    // c - 1
    [c release];
    
    // p - 0  c - 0
    [p release];
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值