【问题标题】:Initializing Global Variables in Obj C在 Obj C 中初始化全局变量
【发布时间】:2015-11-06 20:38:21
【问题描述】:

我正在尝试初始化全局变量,但是我不确定自己做错了什么,因为我收到了一个错误。

现在,我将一个 Globals.h 文件导入到我的 AppDelegate 中。在这里,我声明:

#ifndef Globals_h
#define Globals_h

#endif /* Globals_h */

extern NSArray *CompetencyOne;
extern NSArray *CompetencyTwo;
extern NSArray *CompetencyThree;
extern NSArray *CompetencyFour;
extern NSArray *CompetencyFive;
extern NSArray *CompetencySix;
extern NSArray *CompetencySeven;
extern NSArray *CompetencyEight;
extern NSArray *CompetencyNine;
extern NSArray *CompetencyTen;
extern NSArray *CompetencyEleven;
extern NSArray *CompetencyTwelve;
extern NSArray *Competencies;

然后,我不确定在哪里定义这些数组。我在 AppDelegate.m 中尝试了 didFinishWithLaunchingOptions 方法和 ViewController 的 viewDidLoad 方法,并创建了一个单独的方法,

-(void) initializeCompetencies{ <arrays with values>} 

在 ViewController 中,但我不断收到相同的错误:

Undefined symbols for architecture x86_64:
  "_Competencies", referenced from:
  -[QuestionViewController viewDidLoad] in QuestionViewController.o
  -[QuestionViewController changed:] in QuestionViewController.o
  -[QuestionViewController nextMilestone:] in QuestionViewController.o
  -[QuestionViewController pressBack:] in QuestionViewController.o
  -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyEight", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyEleven", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyFive", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyFour", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyNine", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyOne", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencySeven", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencySix", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyTen", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyThree", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyTwelve", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
  "_CompetencyTwo", referenced from:
      -[QuestionViewController initializeCompetencies] in QuestionViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

知道如何正确声明和初始化全局数组吗?或者,如何解决这个错误?谢谢!

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    Objective-C 对象,除了 NSString 常量,只在运行时创建,因此你不能使用表达式来初始化它们,否则你会得到 error: initializer element is not a compile-时间常数

    如果你声明:

    //Globals.h
    extern NSArray *CompetencyOne;
    
    //Globals.m
    NSArray *CompetencyOne = nil; //this works coz nil is compile time constant
    

    请查看link

    【讨论】:

    • = nil 实际上没有必要,因为所有“静态存储持续时间的对象”都被初始化为零。这来自 C 标准。
    【解决方案2】:

    Sooo,数组很棘手,因为它们不是编译时常量。你必须这样做:

    Constants.h

    extern NSArray *myArray;
    

    Constants.m

    NSArray *myArray = nil;
    

    然后,在应用程序初始化的某个地方,可能应用程序委托确实完成了调用您的函数:

    myArray = @[@1, @2, @3];
    

    【讨论】:

    • 感谢洛根的提醒。澄清一下,我在 .h 和 .m 中的什么位置声明和初始化数组?
    • 直接在文件中的任何位置声明数组,然后在从应用委托调用的全局函数中初始化可能完成启动
    【解决方案3】:

    这听起来更像是您希望一个对象创建不可变数组以供在应用程序内使用。

    一个名为CompentencyFactory 的类怎么样,它有一堆静态方法:

    + (NSArray *) competencyOne;
    + (NSArray *) competencyTwo;
    

    类似这样的等:

    + (NSArray *) competencyOne {
        return @[
            @"foo",
            @"bar",
            @"fubnut"
        ];
    }
    

    您可以在整个应用程序中引用,例如:

    NSArray *comp = [CompetencyFactory competencyOne];
    

    【讨论】:

      【解决方案4】:

      声明和初始化是不够的。您还必须定义变量。

      添加一个 Globals.m 文件并复制声明,删除 extern

      // Globals.m:
      
      NSArray *CompetencyOne;
      NSArray *CompetencyTwo;
      NSArray *CompetencyThree;
      ...
      

      【讨论】:

      • 谢谢。好的,我有一个带有方法 -(void) initializeCompetencies { } 的 Globals.m 文件。现在,如何将这些信息发送到我的 viewController?
      • 你的 Globals.m 应该简单地在类的顶部声明数组,即 NSArray *CompetencyOne = @{....};
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-20
      相关资源
      最近更新 更多