【问题标题】:Objective-C: can initialize one class but not the otherObjective-C:可以初始化一个类但不能初始化另一个
【发布时间】:2020-07-14 22:19:52
【问题描述】:

我有一些带有几个类的 Objective-C 代码。我正在尝试初始化第三类中的前两个类中的每一个。一个工作正常,在 Xcode 中变成正确的颜色并允许我跳转到定义。另一个由于某种原因没有。我已经倒过它,但看不出两者有什么区别。

MainClass.m:

#import "Class1.h"
#import "Class2.h"

@implementation MainClass

Class1 *class1 = [Class1 new];
Class2 *class2 = [Class2 new];

@end

Class1.h:

#ifndef Class1_h
#define Class1_h


@interface Class1 : NSObject

@end

#endif

Class2.h:

#ifndef Class2_h
#define Class2_h


@interface Class2 : NSObject

@end

#endif

Class1.h和Class2.h的头文件没有区别。两者都被导入 MainClass.m 但由于某种原因 Class2 在 MainClass.m 中无法识别,在 Build+Run 上产生“Initializer element is not a compile-time constant”,并且不允许我单击命令并跳转到定义。

我不知道从哪里看这一点。我已将 Class1.m 文件中的代码复制并粘贴到 Class2.m 中,仅更改 #import Class2.h 标头导入和 @implementation Class2 行以确保它不在 .m 文件中...问题仍然存在。

【问题讨论】:

  • 您可能在其他地方有一个挥之不去的#defineClass2_h。顺便说一句,我们一般不会在 Objective-C 中使用 #ifndef/#define 模式。
  • 并且你需要在你的界面中定义实现的方法(即使你从继承的 NSObject 改变了 init),以便 Xcode 可以扫描标题并跳转到正确的。
  • 看起来 mainClass.m 中的 #import "Class2.h" 不起作用。尝试了几十种建议的故障排除技术,现在一切似乎都正常了。谢谢!

标签: objective-c class header initialization


【解决方案1】:

您在第二次导入的末尾有一个撇号而不是双引号。

【讨论】:

  • 是的,抱歉,这只是 SO 问题中的错字
【解决方案2】:

您可能在某处有一个挥之不去的#defineClass2_h。 (如果您使用此 #ifndef/#define/#endif 模式,可能会发生这种情况,尤其是在剪切和粘贴代码时。)


对于它的价值,你真的不需要这个 #ifndef/#define/#endif 模式围绕你的 @interface 引用。 C 程序员经常习惯于使用这种模式,但在 Objective-C 类定义中并不需要它。

例如,考虑Class1 的属性是Class2 的场景:

//  Class1.h

#import "Foundation/Foundation.h"
#import "Class2.h"

@interface Class1 : NSObject

@property (nonatomic, strong) Class2 *class2;

@end

//  Class2.h

#import "Foundation/Foundation.h"

@interface Class2 : NSObject

@end

然后MainClass 可以顺利导入两个标头(即使Class1.h 目前已经导入Class2.h):

//  MainClass.m

#import "MainClass.h"

#import "Class1.h"
#import "Class2.h"

@implementation MainClass

- (void)foo {
    Class1 *class1 = [Class1 new];
    Class2 *class2 = [Class2 new];

    NSLog(@"Class1: %@", class1);
    NSLog(@"Class2: %@", class2);
}

@end

您会认为这种多余的#import "Class2.h" 会导致问题,但事实并非如此。 Objective-C 试图让我们不必担心所有这些 #define 引用。


现在,已经说过,使用上面的示例,Class1.h 甚至可能根本不是 #import 文件 Class2.h,但它可能只是对类进行前向声明。如果Class1 实现需要与Class2 对象进行交互,您将在Class1.m 中执行Class2.h#import,而不是Class1.h

//  Class1.h

#import "Foundation/Foundation.h"

@class Class2;

@interface Class1 : NSObject

@property (nonatomic, strong) Class2 *class2;

@end

但无论如何,我们只是不倾向于在 Objective-C 中使用 #ifndef/#define/#endif 模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2021-11-26
    • 1970-01-01
    相关资源
    最近更新 更多