如何在Objective-C类中使用双向依赖关系来解决这个问题?

时间:2009-05-07 14:26:05

标签: iphone objective-c cocoa cocoa-touch uikit

好的,这可能是一个非常愚蠢的初学者问题,但是:

我有一个ClassA,它将从ClassB创建一个子对象并将其分配给一个实例变量。详细说明:ClassA将在指定的初始化程序中分配和初始化ClassB,并将其分配给childObject实例变量。它的标题如下所示:

#import <Foundation/Foundation.h>
#import "ClassB.h"

@interface ClassA : NSObject {
    ClassB *childObject;
}

@end

然后,有ClassB的标题。 ClassB必须引用ClassA。

#import <Foundation/Foundation.h>
#import "ClassA.h"

@interface ClassB : NSObject {
    ClassA *parentObject;
}

- (id)initWithClassA:(ClassA*)newParentObject;

@end

当ClassA对象从ClassB创建子对象时,ClassA对象将调用ClassB对象的指定初始值设定项,它必须传递给自己(self)。

我觉得有些不对劲,但是现在我并没有得到它的确切含义。有人认为我知道这不起作用。他们不能互相进口。编译器告诉我:“错误:'ClassA'之前的语法错误”。当我删除导入语句以导入ClassA时,删除ClassA * parentObject实例变量并删除指定初始值设定项(需要ClassA引用),然后它可以工作。

现在,这就是我想要实现的目标(如果这很重要):我需要在UIScrollView中使用一些非常特殊和复杂的行为。所以我决定将其子类化。因为主要部分将在委托方法中完成,所以我决定为我的UIScrollView子类创建一个“泛型”委托对象。然后,我的UIScrollView子类自动创建该特殊委托对象并将其分配给其delegate属性。委托对象本身需要引用它的父级,即自定义的UIScrollView,以便它可以访问该滚动视图的子视图。但无论如何,即使有更好的方法来解决这个问题,我仍然想知道如何用两个“相互依赖”的对象来做到这一点。

欢迎任何建议!

3 个答案:

答案 0 :(得分:15)

您无需在头文件中导入这些类。在头文件中使用@class,然后仅在.m文件中使用#import:

// ClassA.h:
@class ClassB;
@interface ClassA : NSObject
{
    ClassB *childObject;
}
@end


// ClassA.m:
#import "ClassA.h"
#import "ClassB.h"
@implementation ClassA
//..
@end


// ClassB.h
@class ClassA;
@interface ClassB : NSObject
{
    ClassA *parentObject;
}
- (id)initWithClassA:(ClassA*)newParentObject;
@end


// ClassB.m:
#import "ClassB.h"
#import "ClassA.h"
@implementation ClassB
//..
@end

答案 1 :(得分:5)

使用@class A;@class B;代替#import来告诉编译器不要担心类定义,只是继续前进,因为它会在以后遇到它们。

基本上,将#import "A.h"替换为@class A;

答案 2 :(得分:5)

您需要做的是“转发声明”您的类而不是导入完整定义。例如:

#import <Foundation/Foundation.h>

@class ClassB; // Tell the compiler that ClassB exists

@interface ClassA : NSObject {
    ClassB *childObject;
}

@end

你为ClassB头文件做了类似的事情。