I have been scratching my head for awhile trying to figure this one out.
我一直在挠头,想弄明白这一点。
I have the following .h files
我有下面的。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
I think the problem is that ClassA needs SomeEnum from ClassB and so it needs to import it, and ClassB needs ClassA for its category so it needs to import it. Is there a problem with them importing each other? Do I need to include a third class?
我认为问题是ClassA需要来自ClassB的一些enum,所以它需要导入它,ClassB需要ClassA为它的类别,所以它需要导入它。他们彼此之间是否存在问题?我需要上第三节课吗?
Here are the compiler errors I'm getting:
下面是我得到的编译器错误:
In ClassB.h: Cannot find interface declaration for 'ClassA'
In ClassA.h: Unknown type name 'SomeEnum'
EDIT: I got it to work by moving the category declaration into ClassA and then having an @class ClassA in ClassB.h...but I'm still not sure why it wouldn't work in the first place
编辑:我通过将类别声明迁移到ClassA,然后在ClassB.h中有一个@class ClassA,使它生效。但我还是不确定为什么它一开始就不奏效。
3 个解决方案
#1
2
Do you have (non-category declaration):
你有(非类别声明):
@interface ClassB
@end
declared anywhere, usually in ClassB.h
?
Or a forward declaration:
在任何地方宣布,通常是在课堂上?或提出声明:
@class ClassB
in ClassA.h
?
在ClassA.h吗?
Try this for your ClassA.h
:
你可以试试这个。
//ClassA.h
@class ClassB
@interface ClassB (Category)
+ (id)classMethod
@end
Then put #import "ClassB.h"
in ClassA.m
.
然后把# ClassB进口”。在ClassA.m h”。
You should put this in ClassA.h
:
你应该把这个放在课堂上。
@interface ClassA (Category) {
}
@end
And then the:
然后是:
@implementation ClassA (Category)
in ClassA.m
above the non-category @implementation ClassA
.
ClassA。m以上非类别@implementation ClassA。
Personally, I create seperate files for categories. For example, this is in UIView-Extended.h:
就个人而言,我为类别创建分离文件。例如,这是在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
And then in UIView-Extended.m
:
然后在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
Then, in my Prefix file (Project-Prefix.pch
):
然后,在我的前缀文件(Project-Prefix.pch):
#import "UIView-Extended.h"
#2
1
You'll want to break out your dependencies. Put the definition of enum SomeEnum
in one header file, then include an import for that header in ClassA.h
and ClassB.h
. In ClassA.h
remove the import of ClassB.h
.
你会想要打破你的依赖关系。在一个头文件中放入enum SomeEnum的定义,然后在ClassA中包含该标题的导入。h和ClassB.h。ClassA。h删除ClassB.h的导入。
#3
0
#import <UIKit/UIKit.h>
you should import <UIKit/UIKit.h>
in any object contains "interface declaration"
你应该< UIKit / UIKit进口。任何对象的h>都包含“接口声明”
e.g: UIImage NSDate etc..
e。旅客:用户界面图像NSDate等。
#1
2
Do you have (non-category declaration):
你有(非类别声明):
@interface ClassB
@end
declared anywhere, usually in ClassB.h
?
Or a forward declaration:
在任何地方宣布,通常是在课堂上?或提出声明:
@class ClassB
in ClassA.h
?
在ClassA.h吗?
Try this for your ClassA.h
:
你可以试试这个。
//ClassA.h
@class ClassB
@interface ClassB (Category)
+ (id)classMethod
@end
Then put #import "ClassB.h"
in ClassA.m
.
然后把# ClassB进口”。在ClassA.m h”。
You should put this in ClassA.h
:
你应该把这个放在课堂上。
@interface ClassA (Category) {
}
@end
And then the:
然后是:
@implementation ClassA (Category)
in ClassA.m
above the non-category @implementation ClassA
.
ClassA。m以上非类别@implementation ClassA。
Personally, I create seperate files for categories. For example, this is in UIView-Extended.h:
就个人而言,我为类别创建分离文件。例如,这是在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
And then in UIView-Extended.m
:
然后在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
Then, in my Prefix file (Project-Prefix.pch
):
然后,在我的前缀文件(Project-Prefix.pch):
#import "UIView-Extended.h"
#2
1
You'll want to break out your dependencies. Put the definition of enum SomeEnum
in one header file, then include an import for that header in ClassA.h
and ClassB.h
. In ClassA.h
remove the import of ClassB.h
.
你会想要打破你的依赖关系。在一个头文件中放入enum SomeEnum的定义,然后在ClassA中包含该标题的导入。h和ClassB.h。ClassA。h删除ClassB.h的导入。
#3
0
#import <UIKit/UIKit.h>
you should import <UIKit/UIKit.h>
in any object contains "interface declaration"
你应该< UIKit / UIKit进口。任何对象的h>都包含“接口声明”
e.g: UIImage NSDate etc..
e。旅客:用户界面图像NSDate等。