Objective-C无法找到接口声明

时间:2011-09-28 23:49:47

标签: objective-c interface import

我一直在摸不着头脑试图想出这个。

我有以下.h文件

//ClassA.h
#import "ClassB.h"

@interface ClassA {
}

@property SomeEnum blah;

@end

//ClassB.h
#import "ClassA.h"

typedef enum SomeEnum
{
     value1,
     value2
}SomeEnum;

@interface ClassB {
}

@property SomeEnum otherblah;

@end

@interface ClassA (Category) {
}

@end

我认为问题在于ClassA需要ClassB中的SomeEnum,因此需要导入它,而ClassB需要ClassA才能进行类别,因此需要导入它。他们互相导入是否存在问题?我需要包括第三节课吗?

以下是我得到的编译器错误:

In ClassB.h: Cannot find interface declaration for 'ClassA'
In ClassA.h: Unknown type name 'SomeEnum'

编辑:我通过将类别声明移动到ClassA然后在ClassB.h中使用@class ClassA来实现它......但是我仍然不确定为什么它不会首先工作

3 个答案:

答案 0 :(得分:2)

你有(非类别声明):

@interface ClassB

@end

在任何地方声明,通常在ClassB.h? 或前瞻声明:

@class ClassB

ClassA.h


试试ClassA.h

//ClassA.h

@class ClassB

@interface ClassB (Category)
+ (id)classMethod
@end

然后将#import "ClassB.h"放入ClassA.m


你应该把它放在ClassA.h

@interface ClassA (Category) {
}

@end

然后是:

@implementation ClassA (Category)
<{1>}位于非类别ClassA.m上方的@implementation ClassA


就个人而言,我为类别创建单独的文件。例如,这是在UIView-Extended.h中:

@interface UIView (UIView_Extended)

enum {
    UIViewAutoresizingHorizontal = (UIViewAutoresizingFlexibleLeftMargin | 
                                    UIViewAutoresizingFlexibleWidth | 
                                    UIViewAutoresizingFlexibleRightMargin),
    UIViewAutoresizingVertical = (UIViewAutoresizingFlexibleTopMargin | 
                                  UIViewAutoresizingFlexibleHeight | 
                                  UIViewAutoresizingFlexibleBottomMargin),
    UIViewAutoresizingAll = (UIViewAutoresizingFlexibleLeftMargin | 
                             UIViewAutoresizingFlexibleWidth | 
                             UIViewAutoresizingFlexibleRightMargin | 
                             UIViewAutoresizingFlexibleTopMargin | 
                             UIViewAutoresizingFlexibleHeight | 
                             UIViewAutoresizingFlexibleBottomMargin)
};
typedef NSUInteger UIViewAutoresizing;

- (UIView *)findFirstResponder;
- (UIView *)setFirstResponder:(NSUInteger)viewTag;
- (IBAction)dismissKeyboard:(id)sender;
- (IBAction)nextPrevious:(id)sender;

@end

然后在UIView-Extended.m

#import "UIView-Extended.h"

@implementation UIView (UIView_Extended)

- (UIView *)findFirstResponder {
    if ([self isFirstResponder]) {
        return self;
    }

    for (UIView *subview in [self subviews]) {
        UIView *firstResponder = [subview findFirstResponder];
        if (firstResponder) {
            return firstResponder;
        }
    }
    return nil;
}

- (UIView *)setFirstResponder:(NSUInteger)viewTag {
    if (self.tag == viewTag) {
        [self becomeFirstResponder];
        return self;
    }
    for (UIView *subview in self.subviews) {
        UIView *v = [subview setFirstResponder:viewTag];
        if (v) {
            return v;
        }
    }
    return nil;
}

- (IBAction)dismissKeyboard:(id)sender {
    [[self findFirstResponder] resignFirstResponder];
}

- (IBAction)nextPrevious:(id)sender {
    UIView *responder = [self findFirstResponder];  
    if (!responder) return;
    NSInteger newTag;
    NSInteger tagMod = 1;
    if (sender) {
        tagMod = (((UISegmentedControl *)sender).selectedSegmentIndex ? 1 : -1);
    }
    UIView *v = [self viewWithTag:responder.tag + tagMod];
    if ([v isKindOfClass:[UITextField class]] || [v isKindOfClass:[UITextView class]]) {
        newTag = responder.tag + tagMod;
        [self setFirstResponder:newTag];
    } else {
        //  do something else... but what??
    }
}

@end

然后,在我的前缀文件(Project-Prefix.pch)中:

#import "UIView-Extended.h"

答案 1 :(得分:2)

你想要打破你的依赖。将enum SomeEnum的定义放在一个头文件中,然后在ClassA.hClassB.h中包含该标头的导入。在ClassA.h中删除导入ClassB.h

答案 2 :(得分:0)

#import <UIKit/UIKit.h>

你应该在包含“接口声明”的任何对象中导入<UIKit/UIKit.h>

e.g: 的UIImage 的NSDate 等。