【问题标题】:Cannot declare variable inside @interface or @protocol不能在@interface 或@protocol 中声明变量
【发布时间】:2011-10-31 19:51:09
【问题描述】:

我从一开始就构建了一个 iOS 应用程序,但其中有一个错误。由于源是从模板开始构建的,它的 appdelegate.h 看起来像:

@interface myAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    myViewController *viewController;
}

BOOL       myBool;     // intended to be globally accessible
NSString   *myString;  // intended to be globally accessible

@end

关于全局变量,我从许多其他 .m 源文件中引用了 myBool*myString

在 XCode 3.2.6 以下,我不记得在编译时遇到任何问题。

在 3.2.6 中,编译时出现警告,指向 appdelegate.h 中的这些“全局”变量,说:“无法在 @interface 或 @protocol 中声明变量”。由于编译或应用程序运行期间没有进一步的问题,很遗憾我没有考虑这些警告。

现在,使用 XCode 4.2,我无法编译此源代码,因为以前的警告变成了构建错误。它们引用并指向不同 .m 文件中引用“全局变量”的每一行。

考虑到我仍想将这些变量/引用作为全局变量/引用来访问,有没有一种简单的方法可以解决这个问题?

其他问题:虽然我正在评估迄今为止收到的答案(感谢大家),但另一个问题:知道为什么在 XCode v3.2.6 下没有给出警告,而在 3.2 中只有警告.6 如果这对我来说是一个真正的错误?为什么代码仍然被编译并且可以毫无问题地运行?

【问题讨论】:

  • 请注意,这种意义上的“全局”变量在面向对象编程中通常是一个坏主意,因为它们违背了局部性和封装性。网上有很多关于这个主题的读物。

标签: iphone ios


【解决方案1】:

他们不能去那里。您可以将它们放在花括号 {} 中,如下所示:

@interface myAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    myViewController *viewController;
BOOL       myBool;     // intended to be globally accessible
NSString   *myString;  // intended to be globally accessible
}

@end

这使得它们对实现类来说是全局的。但是,如果您希望它们对应用程序中的每个类都是全局的,那么您应该将它们放在您的 App-Prefix.pch 文件中:

//
// Prefix header for all source files of the ... project
//
#import <Availability.h>
BOOL       myBool;     // intended to be globally accessible
NSString   *myString;  // intended to be globally accessible
#ifndef __IPHONE_3_0

【讨论】:

  • 我最后做的是创建一个单独的“global_variables.h”文件,将所有这些变量放入其中并使用#import将其包含在appdelegate.h中,它就可以工作了! :)
  • 老实说,这是我见过的最丑陋的语法组合。我知道它是预编译器标志,但它是如此混乱。
【解决方案2】:

您是否试图将它们定义为类的公共成员? Objective-C 中的类与您可能熟悉的其他语言中的类有很大不同。在花括号之外,您只能定义方法。如果您想创建一个可公开访问的成员,请将它们定义为属性:

@interface myAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    myViewController *viewController;
    BOOL _myBool;
    NSString *_myString;
}

@property BOOL       myBool;     // intended to be globally accessible
@property NSString   *myString;  // intended to be globally accessible

@end

然后在您的@implementation 中执行以下操作:

@implementation myAppDelegate
@synthesize myBool = _myBool;
@synthesize myString = _myString;

然后您可以以myObject.myBool 等身份访问它们。

如果您只是想将它们变成类的所有实例的静态(“全局”)数据,那么正如其他发布者所说,您希望将定义移动到您的 .m 文件中(最好声明它们static 所以它们不会导致链接问题)。

【讨论】:

  • 我试图让它们可用于项目中的所有类(这就是我说“全局”的原因)。所以我想让它们可以从所有 .m 文件中访问。
  • 好的,那么从长远来看,您可能想要做的是将它们放在任何@interface 等之外的.h 文件中,并声明它们extern,然后有一个匹配的源声明变量本身的文件(没有任何修饰符)。如果您只是在 .h 中将它们声明为非外部,那么您可能会遇到链接问题。
【解决方案3】:

编译器抱怨变量位于@interface 块中,因此请将它们移出它,可以在@interface 上方或@end 下方。您实际上可能希望在标头中将它们更改为 externs 并在 .m 文件中实际声明它们。

【讨论】:

    【解决方案4】:

    C 全局变量应该在 .m 实现文件中声明,而不是在 .h 头文件中。 extern 声明可以放在 .h 头文件中,通常在 include 之后和接口声明之外。

    将全局对象指针初始化为 nil 也是一个好习惯,否则它们可能包含垃圾对象引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      相关资源
      最近更新 更多