【问题标题】:Objective C Global VariableObjective C 全局变量
【发布时间】:2015-03-09 21:03:45
【问题描述】:

谁能告诉我这里哪里出错了。 我创建了一个名为 BeaconData 的 NSobject。头文件为:

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>

@interface BeaconData : NSObject

@property (nonatomic, strong) NSMutableArray * jsonArray;
@property (nonatomic, retain) NSString * bMajor;
@property (nonatomic, retain) NSString * bMinor;
@property (nonatomic, retain) NSString * bUUID;

-(void) getData;

@end

那么实现文件是:

#import "BeaconData.h"
#define getDataURL @"http://www.eventav.biz/websitebeacons/library/json/files/beacons.txt"

@implementation BeaconData

@synthesize jsonArray, bUUID, bMajor, bMinor;

//Retrieve data
-(void) getData
{
extern NSString * bUUID;
extern NSString * bMajor;
extern NSString * bMinor;

NSURL * url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];

jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

//Loop through Json Array
for (int i = 0; i < jsonArray.count; i++)
{
    bUUID = [[jsonArray objectAtIndex:i] objectForKey:@"i_uuid"];
    bMajor = [[jsonArray objectAtIndex:i] objectForKey:@"i_major"];
    bMinor = [[jsonArray objectAtIndex:i] objectForKey:@"i_minor"];
 }    
}
@end

接下来我尝试在主 viewController.m 文件中调用全局变量 bMajor 并将其打印出来 - 只是看看它是否有效,如下所示:

- (void)viewDidLoad {
[super viewDidLoad];

extern NSString * bMajor;

NSInteger beaconMajorInt = [bMajor integerValue];

NSLog (@"Beacon bMajor is %li", (long)beaconMajorInt);

但我得到的只是以下错误:

架构 x86_64 的未定义符号: “_bMajor”,引用自: -ViewController.o 中的[ViewController viewDidLoad] ld:未找到架构 x86_64 的符号 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

【问题讨论】:

  • 它不是全球性的,你为什么认为它是/希望它是?
  • 为什么不是全球性的?就是那个问题。如果我只是在没有数组的情况下直接初始化变量 - NSString * bMajor = @"47008";像这样 - 然后它就可以了。
  • 它不是一个全局变量。它是一个属性,其值特定于BeaconData 对象的给定实例。
  • 好的 - 那么我如何让它全球化。正如我所说,这是一个有效的问题。如果我不尝试通过外部数据源(即使用数组/字典)对其进行初始化,并将其初始化为 NSString * bMajor = @"47008";那么它工作正常吗??
  • @Mile 只需在实现部分上方声明即可。

标签: objective-c global-variables extern


【解决方案1】:

您已将bMajor 变量声明为类属性。这意味着您必须实例化 BeaconData 类的实例才能访问该变量,除非您包含类方法。

但是,在您的代码中,我看到您还希望将这些变量设为全局变量。将变量声明为类属性然后尝试使其成为全局变量是多余的。在objective-c中,简单地在实现部分之外声明一个变量将使它对于所有导入带有声明的文件的模块都是全局的。你这样做:

NSString *bMajor = @"Your String";

@implementation BeaconData
// YOUR CLASS CODE
@end

您错误地使用了extern 关键字。它应该在 .h 类文件中使用,以让任何导入它的东西都知道他们可以访问这个变量。 您还必须像我在 .m 类文件中显示的那样声明它

.h 看起来像这样:

extern NSString *bMajor;

@interface BeaconData : NSObject
@end

仅仅因为您可以这样做并不意味着您应该这样做。根据您的代码,我怀疑您想要做的是将您的 -getData 实例方法转换为单例的类方法,允许类管理这些“全局”变量,同时保持良好的编码习惯。

This SO Q/A should provide you exactly what you need to create your singleton.我建议你这样做。

然后在您的 viewController 中,您将通过使用 class 方法获取您的类的实例来访问这些变量。

【讨论】:

  • 谢谢。我实际上看过单例方法,但我认为这种方法会更容易。我将恢复为单例方法。感谢您的帮助:)
猜你喜欢
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
相关资源
最近更新 更多