Cocoa/Objective-C中的全局变量?

Joh*_*udy 19 cocoa global-variables objective-c

根据Cocoa Programming for Mac OS X,3rd Edition,第202页(第13章):

您将在应用程序的多个类中注册,读取和设置默认值.为了确保始终使用相同的名称,您应该在单个文件中声明这些字符串,然后简单地#import该文件到您使用名称的任何文件中.有几种方法可以做到这一点.例如,您可以使用C预处理器的#define命令,但大多数Cocoa程序员为此目的使用全局变量.

这真的是最正确的最佳做法吗?全局变量?这对我来说似乎很疯狂 - 反对我曾经教过的一切.

更好的设计是一个简单的Singleton类,并定义了这些?或者走向全球是否真的是最佳做法?考虑到许多人认为单身人士穿着漂亮的连衣裙是全球性的吗?

Bar*_*ark 63

为了清楚起见,建议创建不可变的全局变量而不是内联字符串常量(难以重构和无编译时检查)或#defines(无编译时检查).这是你怎么做的......

在MyConstants.h中:

extern NSString * const MyStringConstant;
Run Code Online (Sandbox Code Playgroud)

在MyConstants.m中:

NSString * const MyStringConstant = @"MyString";
Run Code Online (Sandbox Code Playgroud)

然后在任何其他.m文件中:

#import "MyConstants.h"

...
[someObject someMethodTakingAString:MyStringConstant];
...
Run Code Online (Sandbox Code Playgroud)

这样,你获得编译时检查,你没有拼错字符串常量,你可以在比较你的常量时检查指针相等而不是字符串相等[1],并且调试更容易,因为常量有一个运行时间字符串值.

[1]在这种用法中,您实际上是使用指针值作为常量.碰巧这些特定的整数也指向可以在调试器中使用的字符串

  • "const NSString"并不意味着什么; 无论如何,constness将被消息发送忽略.Cocoa中的字符串常量通常声明为<code> extern NSString*const NSFoo; </ code>,这意味着<em>指针</ em>是只读的.字符串对象当然是不可变的. (5认同)

Gra*_*erg 18

全局变量或单例将在这里完成相同的事情.两者都可以用来在Cocoa中转换"密钥"名称,如果拼写错误导致编译器错误,则不会引发编译器错误.这是主要目的.全局变量虽然看起来更简单,因为它需要更少的输入.

而不是这样做:

[myArray setObject:theObject forKey:MyGlobalVariableKeyName];
Run Code Online (Sandbox Code Playgroud)

你必须做一些事情:

[myArray setObject:theObject 
            forKey:[[MySingletonVariableClass getInstance] myVariableKeyName];
Run Code Online (Sandbox Code Playgroud)

对于相同的效果,全局变量本质上更少.


Mat*_*her 18

将其称为全局变量在技术上是正确的,但具有误导性.

它是一个全局常量 - 全局范围但是不变,因此在全局变量不好的意义上并不坏.

为了说明全局常量如何通用,安全且众多,请考虑以下全局常量示例:

  • 您计划中的每个班级
  • 每个#define
  • 每个枚举
  • 几乎每个Cocoa声明的名称(不包括罕见的全局变量NSApp).

你应该担心全局常量的唯一一次是它们的名称过于通用(它们可能会污染全局命名空间).所以不要使用可能与任何东西冲突的名称(总是使用前缀并始终使名称与特定任务相似NSKeyValueObservingOptionNew).