在cocoa中声明静态变量

时间:2012-10-04 17:54:41

标签: cocoa class variables static

我想在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;
}

那么简单的静态声明方法是否有任何问题,而不是更复杂的类函数方法?我错过了什么?

1 个答案:

答案 0 :(得分:7)

首先,你要求的是一个全局变量,一个静态类似但有点不同......

在标题(static)文件中的@interface之外放置.h声明会在每个实现中创建不同的变量({{1} })文件包括标题 - 在这种情况下不是你想要的。

因此声明.m会创建一个变量,其 lifetime 是整个应用程序执行的变量,但在编译单元中只有 visible (例如它出现的实现文件 - 直接或通过包含。

要创建一个全局变量,您需要在标题中使用static

extern

并在您的实现中重复声明而不使用extern NSString *id;

extern

关于全局变量与类方法有什么问题,这是关于程序设计和可维护性的问题。以下是几点需要考虑的问题:

  • 使用方法除非提供setter方法和getter方法,否则无法更改该值。变量总是可读写的。
  • 命名空间污染:类方法仅在与其类名称(NSString *id; )配对时才有效;变量名在任何地方都有效,只包含[YourClass id];这既污染了名称空间又失去了idid之间的联系 - 这导致我们......
  • 封装:全局变量破坏了强大的封装,封装有助于程序设计和维护 - 这是一个很大的话题。

也就是说,全球有时间和地点,有时候......

问题更新后

在实现中声明的YourClass变量实际上是一个“类变量” - 一个由类的所有实例共享的变量。

类变量与setter&的pros'n'cons。 getter类方法与实例变量与属性&的pros'n'cons完全相同。 setter / getter实例方法。

类setter / getters允许在每次读/写时执行验证和其他逻辑;和内存管理的本地化 - 简而言之,任何方法的抽象和封装优势。

因此,您使用变量还是setter / getter取决于您的应用程序。这与使用实例变量或setter / getter / property是一样的问题。