@class

本文详细解释了Objective-C中循环引用的原理及解决方法,并通过实例展示了如何使用`retain`、`assign`、`weak`和`strong`关键字进行兼容ARC和非ARC编程。同时介绍了循环引用在ARC环境下的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//

//  main.m

//  循环retain

//

//  Created by amesty on 15-1-8.

//  Copyright (c) 2015 itcast. All  rights reserved.


/*开发中类规范:

1.   .h 文件中@class的作用仅仅声明某个名称是一个类 @class Card;

2.   .m  文件中用#import来包含类的所有东西。(import是拷贝)

    Card这个文件中被其他100类引用,意味着Card改变100份文件中均要重新编译

3.两端循环引用解决方案

  1》一端用retain   ----strong

  2》一端用assign   ----weak

 让程序兼容ARC和非ARC部分。转变为非ARC  -fno-objc-arc  转变为ARC的, -f-objc-arc 

 

 ARC也需要考虑循环引用问题:一端使用strong,另一端使用weak

 

 */


#import <Foundation/Foundation.h>

#import "Person.h"

#import"Card.h"


int main(int argc, const char * argv[])

//p=1

    Person *p=[[Person alloc]init];

    

  //c=1

    Card *c=[[Card allocinit];

    

   // p=2

    p.card=c;

    // p=2

    c.person=p;

    

    //c=1

    // p=1


    return 0;

}

===========


//  Person.h

//  循环retain

//

//  Created by amesty on 15-1-8.

//  Copyright (c) 2015 itcast. All rights reserved.

//


#import <Foundation/Foundation.h>

//#import"Card.h"

@class Card;

@interface Person: NSObject

@property (nonatomic,weakCard *  card;

@end

==============

//

//  Person.m

//  循环retain

//

//  Created by amesty on 15-1-8.

//  Copyright (c) 2015 itcast. All rights reserved.

//


#import "Person.h"

#import"Card.h"

@implementation Person

-(void)dealloc

{   NSLog(@"car被销毁了");

    


}

@end

================

//  Card.h

//  循环retain

//

//  Created by amesty on 15-1-8.

//  Copyright (c) 2015 itcast. All rights reserved.

//


#import <Foundation/Foundation.h>

//#import"Person.h"

@class Person;

@interface Card : NSObject

@property (nonatomic ,strong)Person * person;


@end

==============

//  Card.m

//  循环retain

//

//  Created by amesty on 15-1-8.

//  Copyright (c) 2015 itcast. All rights reserved.

//


#import "Card.h"

#import "Person.h"

@implementation Card

-(void)dealloc

{    NSLog(@"Person被销毁了");


}

@end

================

objective-c中#import和@class的区别

在Objective-C中,可以使用#import和@class来引用别的类型, 但是你知道两者有什么区别吗?

@class叫做forward-class,  你经常会在头文件的定义中看到通过@class的引用, 原因就是当你只用@class来引入一个类时, 编译器知道有这么一个类,也就是说它能识别Engine *engine;


而在implementation文件中,如果你想要访问engine.price, 编译器就会出错, 即使你用了@class引入了. 这时需要使用的其实是#import 来引入Engine.h这个头文件,它包括这个类的所有的定义, 它知道你有定义一个price, 而通过@class引入的除了类本身之外,没有具体的信息.


更详细的分析:在Objective-c中,当一个类需要引用另一个类的接口时,需要在类的头文件中建立被引用类的指针

Person.h

@interface Person: NSObject

{

   Woman *woman;

   Man *man;

}

.......

如果直接编译,会出错,因为不知道Woman,Man是什么。

这时有两个选择,一是import这两个被引用类的头文件,另一个是使用@class申明Woman和Man是类名,二者的区别:

1. import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你;

2. 在头文件中,一般只需要知道被引用的类的名称就可以了,不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称,而在类的实现部分,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。

3. 在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次被引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。

4. 如果有循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。

所以,一般来说,@class是放在interface中的,只是为了在interface中引用这个类,把这个类作为一个类型来用的。 在实现这个接口的实现类中,如果需要引用这个类的实体变量或者方法之类的,还是需要import在@class中声明的类进来.










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值