我想在Cocoa中有一个静态变量。
在查看How do I declare class-level properties in Objective-C?之后,我不清楚到目前为止我所做的事情是否有任何问题,即
// Foo.m
static NSString* id;
@interface Foo ()
而不是
// Foo.h
@interface Foo {
}
+(NSString*) id;
// Foo.m
+(NSString*) id
{
static NSString* fooId = nil;
if (fooId == nil)
{
// create id
}
return fooId;
}
显然,第二种方法提供了初始化id的机会。但是如果我在代码中的其他地方自己初始化id,那么就说一个getter:
-(NSString*) getId
{
if (id==nil) {
id = ... // init goes here
}
return id;
}
那么简单的静态声明方法是否有任何问题,而不是更复杂的类函数方法?我错过了什么?
答案 0 :(得分:7)
首先,你要求的是一个全局变量,一个静态类似但有点不同......
在标题(static
)文件中的@interface
之外放置.h
声明会在每个实现中创建不同的变量({{1} })文件包括标题 - 在这种情况下不是你想要的。
因此声明.m
会创建一个变量,其 lifetime 是整个应用程序执行的变量,但在编译单元中只有 visible (例如它出现的实现文件 - 直接或通过包含。
要创建一个全局变量,您需要在标题中使用static
:
extern
并在您的实现中重复声明而不使用extern NSString *id;
:
extern
关于全局变量与类方法有什么问题,这是关于程序设计和可维护性的问题。以下是几点需要考虑的问题:
NSString *id;
)配对时才有效;变量名在任何地方都有效,只包含[YourClass id]
;这既污染了名称空间又失去了id
和id
之间的联系 - 这导致我们...... 也就是说,全球有时间和地点,有时候......
问题更新后
在实现中声明的YourClass
变量实际上是一个“类变量” - 一个由类的所有实例共享的变量。
类变量与setter&的pros'n'cons。 getter类方法与实例变量与属性&的pros'n'cons完全相同。 setter / getter实例方法。
类setter / getters允许在每次读/写时执行验证和其他逻辑;和内存管理的本地化 - 简而言之,任何方法的抽象和封装优势。
因此,您使用变量还是setter / getter取决于您的应用程序。这与使用实例变量或setter / getter / property是一样的问题。