在cocoa中声明静态变量

Lol*_*olo 3 variables cocoa static class

我想在Cocoa中有一个静态变量.

看看如何在Objective-C中声明类级属性?,我不清楚到目前为止我所做的事情是否有任何问题,即

// Foo.m
static NSString* id;
@interface Foo ()
Run Code Online (Sandbox Code Playgroud)

代替

// Foo.h
@interface Foo {
}

+(NSString*) id;

// Foo.m
+(NSString*) id
{
  static NSString* fooId = nil;

  if (fooId == nil)
  {
    // create id
  }

  return fooId;
}
Run Code Online (Sandbox Code Playgroud)

显然,第二种方法提供了初始化id的机会.但是,如果我自己在代码中的其他地方初始化id,在一个getter中说:

-(NSString*) getId
{
    if (id==nil) {
      id =  ... // init goes here
    }
    return id;
}
Run Code Online (Sandbox Code Playgroud)

那么简单的静态声明方法与更复杂的类函数方法相比有什么不对吗?我错过了什么?

CRD*_*CRD 7

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

在header()文件中static的any之外放置一个声明将在每个implementation()文件中创建一个不同的变量,包括标题 - 在这种情况下不是你想要的.@interface.h.m

因此static,在声明中创建一个变量,其生命周期是整个应用程序执行的变量,但只能在它出现的编译单元(例如实现文件)中可见 - 直接或通过包含.

要创建一个全局变量,您需要extern在标头中使用它:

extern NSString *id;
Run Code Online (Sandbox Code Playgroud)

并在您的实现中重复声明,而不是extern:

NSString *id;
Run Code Online (Sandbox Code Playgroud)

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

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

也就是说,全局变星可能有时间和地点,有时......

问题更新后

static在实现中声明的变量实际上是一个"类变量" - 一个由类的所有实例共享的变量.

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

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

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