在cocoa中声明静态变量

在cocoa中声明静态变量,cocoa,class,variables,static,Cocoa,Class,Variables,Static,我想在Cocoa中有一个静态变量 在看了之后,我不清楚到目前为止我一直做的事情是否有任何问题,即 // 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

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

在看了之后,我不清楚到目前为止我一直做的事情是否有任何问题,即

// 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;
}

那么,与更复杂的类函数方法相比,简单的静态声明方法有什么问题吗?我遗漏了什么?

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

在头文件(
.h
)中的任何
@接口
之外放置一个
静态
声明将在每个实现(
.m
)文件中创建一个不同的变量,您将头文件包含在其中,而不是本例中所需的变量

因此,声明上的
static
创建了一个变量,该变量的生命周期是整个应用程序执行的生命周期,但该变量仅在其出现的编译单元(例如,实现文件)中可见,可以直接显示,也可以通过包含来显示

要创建随处可见的全局变量,需要在标题中使用
extern

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

NSString *id;
至于全局变量与类方法的区别,这是一个关于程序设计和可维护性的问题。以下是需要考虑的几点:

  • 对于方法,除非提供setter方法和getter方法,否则不能更改该值。变量总是读写的
  • 命名空间污染:类方法仅在与其类名(
    [YourClass id]
    )配对时才有效;变量名在任何地方都有效,只需将其包含为
    id
    ;这既污染了名称空间,也失去了
    id
    YourClass
    之间的联系,这导致我们
  • 封装:全局变量打破了强大的封装,而封装有助于程序的设计和维护——这是一个大话题
也就是说,全球人有时会有时间和地点

问题更新后

实现中声明的
静态
变量实际上是一个“类变量”——一个由类的所有实例共享的变量

类变量对setter和getter类方法的利弊与实例变量对properties和setter/getter实例方法的利弊完全相同

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


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

但不能同时提供在方法级静态变量上运行的getter和setter方法;这两个方法可能都有相同名称的静态变量,但它们是不同的。如果在类接口文件中使用编译单元级静态变量,类方法使用的静态变量是否总是相同的变量,而#导入该类接口文件的实现文件实际上设置了具有相同名称但不同的静态变量?这似乎应该是正确的,因为类实现可能是与导入其接口的其他实现分开编译的;但是我想肯定地知道。@echristopherson-正确的,方法级静态变量在声明它们的方法的可见性方面是有限的。基于变量的类级别setter和/或getter方法将对类级别的静态变量进行操作。在任何方法或函数之外的实现文件中声明的任何静态变量都是类级别的静态变量,相当于某些其他语言中的“类变量”。将此类声明放置在
@实现
块内(以及该块中所有其他内容之外)的逻辑位置为了直观地表明它们属于类。@echristopherson-re:头文件中的编译单元级静态变量-是,在包含头文件的每个编译单元中都会创建一个不同的变量。头文件中的静态变量声明相当模糊,您很少会(或者应该!)遇到它们。我的意思是静态变量,我的意思是在m文件中显示分配的静态变量,而不是像我的评论所建议的那样在h文件中。我正在修改我原来的帖子。我理解globals的缺点,并且只对我在我的帖子中提到的两种方法的不同感兴趣。