在Objective-C中声明全局变量的正确方法是什么

在Objective-C中声明全局变量的正确方法是什么,objective-c,Objective C,所以,我想知道在iOS项目中声明全局变量的正确方法是什么。 我不希望将其设置为属性,因为该变量不应从类外部访问 我将提供一些我见过的方法,让我知道哪种方法是正确的,如果有其他更好的方法 通过这种方式,我将全局变量添加到实现文件.m中@interface声明之后的花括号中。然后我可以在viewDidLoad #import "ViewController.h" @interface ViewController () { int globalVariableTest; } @end @

所以,我想知道在iOS项目中声明全局变量的正确方法是什么。 我不希望将其设置为属性,因为该变量不应从类外部访问

我将提供一些我见过的方法,让我知道哪种方法是正确的,如果有其他更好的方法


通过这种方式,我将全局变量添加到实现文件
.m
@interface
声明之后的花括号中。然后我可以在
viewDidLoad

#import "ViewController.h"

@interface ViewController () {
    int globalVariableTest;
}
@end

@implementation ViewController
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController {
       int globalVariableTest;
}
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

int globalVariableTest = 1;

另一种方法是在实现文件
.m
中的
@implementation
声明之后添加大括号内的全局变量。在
viewDidLoad

#import "ViewController.h"

@interface ViewController () {
    int globalVariableTest;
}
@end

@implementation ViewController
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController {
       int globalVariableTest;
}
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

int globalVariableTest = 1;
另一种方法是在
@实现
之后添加变量,而不使用大括号,这也允许我在不使用
viewDidLoad的情况下设置初始值

#import "ViewController.h"

@interface ViewController () {
    int globalVariableTest;
}
@end

@implementation ViewController
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController {
       int globalVariableTest;
}
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

int globalVariableTest = 1;
另一种方法是在头文件
.h

@interface ViewController : UIViewController
{
    int globalVariableTest;
}

因此,如果有更好的方法,请让我知道,所有的帮助将不胜感激

您可以使用单例类在不同的类(视图控制器)之间创建/共享(读/写)所有变量

h

共享变量

#import "SharedVariables.h"

@implementation SharedVariables
@synthesize dicti_StackSites;
@synthesize dicti_UserMe;

+(id)sharedVariablesManager {
    static SharedVariables *sharedVariablesClass = nil;
    @synchronized(self) {
        if (sharedVariablesClass == nil) {
            sharedVariablesClass = [[self alloc] init];
        }
    }
    return sharedVariablesClass;
}

-(id)init {
    if (self = [super init]) {
        dicti_StackSites = [[NSDictionary alloc] init];
        dicti_UserMe = [[NSDictionary alloc] init];
    }
    return self;
}

-(void)dealloc {
}

@end
任何其他类别的用法

#import "SharedVariables.h"

SharedVariables *sharedManager = [SharedVariables sharedVariablesManager];

//to get sharedManager.dicti_StackSites
//to set sharedManager.dicti_StackSites = ...

在花括号内声明变量实际上是声明一个实例变量,简称“ivar”。也就是说,是类实例的局部变量

这过去只能在
@interface
声明之后才能实现,这就是为什么有时会在那里看到它。这在Xcode 4周围发生了变化,因此现在您可以在
@实现之后执行它。据我所知,这只是风格偏好。IVAR在类之外是永远不可访问的(理论上,在技术上,C中的所有东西都可以访问),因此在.h中定义IVAR不会使它们公开。不过,它确实公开了一个实现细节,这就是我现在看到的大多数使用它们的代码将它们放在
@implementation
中的原因

但是我不再在代码中看到它们了。因为当你定义一个
@property
时,实际上发生在封面下的是一个ivar、一个getter方法和一个setter方法,它们实际上都在为你合成。getter和setter方法只是分别获取ivar的值和设置ivar的值

因此,如果您想要的是与属性具有相同作用域的内容,但是没有
-myVar
-setMyVar:
方法,那么这是正确的方法

但你可能不想这样。有很多原因表明,只通过访问器方法访问IVAR是很好的。它允许您覆盖功能、转换值以及抽象提供给您的所有其他有趣的东西

如果您想要的是类外无法访问的
@属性
,只需在类扩展中声明它:

//In MyClass.m
@interface MyClass()
  @property NSNumber *myProperty;
@end

@implementation MyClass
  //All your implementation stuff here.
@end
因为它不在.h文件中,所以它不会对其他类“可见”(理论上,请参见上文关于C中的所有可见内容)

另一方面,如果您真正想要的是真正全局的东西(提示:您不应该这样做。全局变量通常有一种糟糕设计的味道),那么您需要在任何
@接口
@实现
块之外的文件顶部定义它


另一个相关的花絮:要定义一个“全局”变量,其作用域仅限于给定的文件,请查看C的
static
关键字。有趣的是。

真正的全局变量在.m文件中定义为
int-globalVariableTest
,在.h文件中声明为
extern-int-globalVariableTest
。然后,导入h。文件转换为希望访问该变量的每个其他.m文件。顺便说一下,这不仅在Objtovi-C中有效,而且在C和C++中也是有效的。我看到它有这么多不同的方式,有区别吗?在任何
@接口
/
@end
@实现
/
@end
块之外(在所谓的“全局范围内”);例如,在最顶部附近(在导入之后)。顺便说一句,您尝试使用的是一个实例变量,它只在视图控制器的实例存在时持续。我解释的是一个全局变量,没有附加到任何瞬态对象。它贯穿于应用程序的整个生命周期。“我在@interface声明之后的花括号中添加了全局变量”-那么这绝对不是全局变量。他在评论中提到,他只在视图控制器的生命周期中需要该变量,所以我认为他不需要单身汉…@NicolasMiari我没有读评论。问题或评论有误,那么dicti_StackSites不应该被明确发布吗?我在问题中误用了术语Global。我道歉。然而,我认为你准确地回答了我的问题。澄清。在
.h
中,如果导入,则可以从另一个类中看到在此设置的属性。但是,如果我只想从这个特定类访问变量,请在
.m文件的
@interface
中声明它?我一直想知道
@interface
.m文件中的作用是什么
没错!如果您只需要知道这些,请停止阅读,但如果您想了解详细信息:一个
@接口
块后跟一个
()
,而不是一个超类,实际上是在定义一个ObjC类别。通常,您必须在参数中指定一个名称,以及与该名称匹配的单独的
@实现
,但不指定任何内容会使其成为匿名类别,有时也称为类扩展。它的唯一用途是让您为.h文件之外的内容定义接口,以便