1

根据这个答案,我试图声明和定义全局变量并得到这个错误:

   架构 armv7 的未定义符号:
     “_loggedIn”,引用自:
      -[XYZAppDelegate 应用程序:didFinishLaunchingWithOptions:] 在 XYZAppDelegate.o
      -[XYZFolderViewController viewDidAppear:] 在 XYZFolderViewController.o
      -[XYZFolderViewController loginViewController:didEnterUsername:password:] 在 XYZFolderViewController.o
ld:未找到架构 armv7 的符号
clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

我在这里找到了很多答案,但它们都指的是不同的问题(据我所知)。

XYZAppDelegate.h

...
extern BOOL 登录;
...

XYZAppDelegate.m:

...
@implementation XYZAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    登录 = 0;
    ...
}
...

XYZFolderViewController.h

...
extern BOOL 登录;
...

XYZFolderViewController.m

...
@执行
...
- (void)loginViewController:(XYZLoginViewController *)loginViewController
           didEnter用户名:(NSString *)用户名
                   密码:(NSString *)密码
{
...

    if ([username isEqualToString:theUsername] && [password isEqualToString:thePassword])
    {
        登录 = 1; /* 0 == 未登录。 1 == 已登录。 */
        ...
    }
...
}

此全局变量的要点是保存有关用户登录(或未登录)到应用程序的信息。我知道extern在 Objective-C 中使用不是干净的方法。但是,除了extern使用之外,我会感谢其他类型的解决方案的提示。期待这是菜鸟问题。

4

3 回答 3

6

extern意思是:“这个东西是在别的地方定义的”

所以,你没有声明一个全局变量。你只是说别人是并且你想使用它。因此,当编译器试图找到它并出现空白时,它会告诉您它找不到定义。

并不是说您应该为此尝试使用全局变量,您不应该这样做,但可以使用static.

您应该将loggedIn标志设置为实例变量,并提供对该值的正确、只读访问权限。这意味着公开只读,但私有可写。因此只能在类内部更改状态(作为 的结果loginViewController:...)。

因此,在 .h 文件中,您将拥有:

@property (assign, nonatomic, readonly) BOOL loggedIn;

然后在 .m 文件中:

@property (assign, nonatomic, readwrite) BOOL loggedIn;
于 2013-07-04T20:06:13.583 回答
1

在您的应用程序中使状态全局可用通常不是一个好主意。您应该始终尝试将可变状态保持在最低限度。阅读这篇文章或查看函数式编程原理课程,这些课程非常有助于您开始成为一名更好的程序员。

extern关键字最适合使常量对象随处可用。例如 NSStrings。像这样:

常量.h

extern NSString* kAKeyPath; 
extern double kPI;

常数.m

NSString * const kAStringContant = @"contact.name";
const double kPI = 3.14159265359;

以这种方式使用值是有利的,因为编译器可以为您检查它(它不仅仅是您需要记住的字符串或 int 值)并且它将存储在程序数据存储中的一个实例中(与存储它相比多次如果extern不使用,它们会出现)。

于 2013-07-04T21:35:14.140 回答
0

一个问题可能是,如果您有多个目标,您已经导入了包含变量存在承诺的 .h 文件,但您没有包含 .c 或 .m,因此您缺少具有该符号的编译单元。当然你可以在没有多个目标的情况下进入这个状态,但是由于 Xcode 会自动将 .m 添加到默认目标,你通常不会进入那个状态。

于 2013-07-04T21:40:36.913 回答