黑马程序员技术交流社区

标题: 关于类的循环引用,求大神指点迷津,和老师敲得一样啊! [打印本页]

作者: D调的沉默    时间: 2014-5-3 15:26
标题: 关于类的循环引用,求大神指点迷津,和老师敲得一样啊!
本帖最后由 D调的沉默 于 2014-5-4 11:39 编辑

关于类的循环引用,老是和我报头文件错误,未知类型错误,不知道可有遇到同样问题的同学。
代码如下car.h

  1. #import <Foundation/Foundation.h>
  2. #import "Person.h"
  3. @interface Car : NSObject

  4. @property (nonatomic,retain) Person *person;

  5. @end
复制代码

car.m

  1. #import "Car.h"

  2. @implementation Car
  3. -(void)dealloc
  4. {
  5.     [_person release];
  6.     NSLog(@"car is dealloc");
  7.     [super dealloc];
  8. }

  9. @end
复制代码
person.h
  1. #import <Foundation/Foundation.h>
  2. #import "Car.h"

  3. @interface Person : NSObject
  4. @property(nonatomic,retain) Car * car;

  5. @end
复制代码

peron. m
  1. #import "Person.h"

  2. @implementation Person
  3. - (void)dealloc
  4. {
  5.     [_car release];
  6.     NSLog(@"person is dealloc");
  7.     [super dealloc];
  8. }


  9. @end
复制代码
main .m
  1. #import <Foundation/Foundation.h>
  2. #import "Person.h"
  3. #import "Car.h"
  4. int main(int argc, const char * argv[])
  5. {
  6.     Person * person = [[Person alloc] init];
  7.     Car *car = [[Car alloc] init];
  8.     person.car = car;
  9.     car.person = person;
  10.    
  11.     [person release];
  12.     [car release];
  13.    
  14.     return 0;
  15. }
复制代码
错误提示如下




作者: D调的沉默    时间: 2014-5-3 15:35
不知道,你们图片可能看到,我不知道为什么我编辑的时候能看到,但是在发表后看不到,这里手打一下错误提示
在person。h文件中@property(nonatomic,retain)Car *car处提示:property with “retain”(or strong)attribute must be of object type
在perosn。m文件中【_car release】提醒 use of undeclared identifier "_car",但是我头文件中都包含了#import “car。h”了,我看老师这么写的也没错啊

作者: dawn.dai    时间: 2014-5-3 15:36
本帖最后由 dawn.dai 于 2014-5-3 15:47 编辑

你person.h引用car.h,car.h引用person.h这样循环引用肯定会有问题,不要两边都import头文件,其中一个@class  另一个类名声明一下,具体调用再在.m中import头文件就行了,还提高性能;成员变量中也要一边用retain,一边用assign;
#import <Foundation/Foundation.h>
@class car;//知道是这么各类就行

@interface person : NSObject
@property(nonatomic,retain) car * car;

@end


#import <Foundation/Foundation.h>
#import "person.h"
@interface car : NSObject

@property (nonatomic,assign)person *person;


@end

#import "person.h"
#import "car.h"//具体实现再导入

@implementation person


@end


作者: D调的沉默    时间: 2014-5-3 16:25
dawn.dai 发表于 2014-5-3 15:36
你person.h引用car.h,car.h引用person.h这样循环引用肯定会有问题,不要两边都import头文件,其中一个@clas ...

这个我知道啊,如果是两个类循环引用,要用@class 类名才能解决问题,但是我现在敲得是老师没改@class之前的代码,老师也是这么敲没什么问题,只不过car 和person都没有释放,即调用dealloc方法。我想知道为什么没改版之前我得是错误的,老师的运行没问题
作者: dawn.dai    时间: 2014-5-3 18:28
D调的沉默 发表于 2014-5-3 16:25
这个我知道啊,如果是两个类循环引用,要用@class 类名才能解决问题,但是我现在敲得是老师没改@class之 ...

不可能吧  老师也不能开小灶,你仔细看看
作者: D调的沉默    时间: 2014-5-3 19:16
dawn.dai 发表于 2014-5-3 18:28
不可能吧  老师也不能开小灶,你仔细看看

不知道,上面的代码是我全部敲的,如果不换成@class你看有什么问题吗?如果只是换成@class,那跟老师讲的一样我就没必要问了,我初步怀疑是不是xcode版本的问题,所以就想问问论坛的人是不是也遇到过这样的问题。
作者: siegee    时间: 2014-5-3 21:18
本帖最后由 siegee 于 2014-5-3 21:28 编辑

用前置声明只为了方便程序员,提高编译效率。当然这位同学所遇到的问题是经典的两对象指针的强引用,在程序退出时,由于强引用,没有了主次之分,指针的引用计数都大于1。这时就都无法销毁对象,也就不会调用dealloc方法,造成了内存泄漏。所以必须有弱引用的一方。当使用@class在两个类相互声明,也不会出现编译报错。
作者: D调的沉默    时间: 2014-5-3 22:13
siegee 发表于 2014-5-3 21:18
用前置声明只为了方便程序员,提高编译效率。当然这位同学所遇到的问题是经典的两对象指针的强引用,在程序 ...

答非所问,能不能仔细看下问题。。。
作者: siegee    时间: 2014-5-3 22:44
D调的沉默 发表于 2014-5-3 22:13
答非所问,能不能仔细看下问题。。。

大哥,简单的说就是你不该都retain。@property(nonatomic,retain) Car * car;@property (nonatomic,retain) Person *person;
作者: D调的沉默    时间: 2014-5-4 10:16
siegee 发表于 2014-5-3 22:44
大哥,简单的说就是你不该都retain。@property(nonatomic,retain) Car * car;@property (nonatomic,reta ...

大哥我知道不应该都用retain,但是我像问的是老师没修改前两方都用retain,而且没用@class声明,都没报错误,只是没打印出来dealloc的结果,而我同样这样写,却提示头文件错误。
      你能不能看看楼上的回答和提问,和仔细看下问题,你说的这种解决方式我懂,而且是老师视屏里说的方式,如果单单是按照视屏上老师的方式就能解决,我都看过了,我肯定知道咋解决,我肯定不来这问。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2