Objective-C中的#define vs const
我是Objective-C的新手,我有几个关于const和预处理指令#define 。 
 首先,我发现使用#define定义常量的types是不可能的。 这是为什么? 
其次,使用其中一个有什么好处?
最后,哪种方式更有效率和/或更安全?
首先,我发现它不可能使用#define定义常量的types,为什么呢?
为什么是什么? 这不是真的:
 #define MY_INT_CONSTANT ((int) 12345) 
其次,使用其中一个有什么好处?
 是。  #define定义了一个在编译开始之前被replace的macros。  const只是修改一个variables,以便编译器会在你尝试修改的时候标记一个错误。 有些情况下你可以使用#define但是你不能使用const (虽然我正在努力寻找一个使用最新的clang)。 理论上, const在可执行文件中占用空间并需要对内存的引用,但实际上这并不重要,可能会被编译器优化掉。 
  const比#define更适合编译器和debugging器。 在大多数情况下,在决定使用哪一个时,这是您应该考虑的重点。 
 只是想到你可以使用#define而不是const的上下文。 如果你有一个常量,你想在很多.c文件中使用#define你只要把它放在一个头文件中。 用const你必须在C文件中定义一个 
 // in a C file const int MY_INT_CONST = 12345; // in a header extern const int MY_INT_CONST; 
 在标题中。 除了定义的C文件外, MY_INT_CONST不能用作任何C文件中静态或全局作用域数组的大小。 
 但是,对于整数常量,您可以使用enum 。 事实上,苹果几乎总是这样做。 这具有#define s和const s的所有优点,但只适用于整数常量。 
 // In a header enum { MY_INT_CONST = 12345, }; 
最后,哪种方式更有效率和/或更安全?
  #define理论上更有效率,但正如我所说,现代编译器可能确保没有什么区别。  #define更安全,因为尝试分配给它总是一个编译器错误 
 #define FOO 5 // .... FOO = 6; // Always a syntax error 
虽然编译器可能会发出警告,但consts可以被诱骗分配给:
 const int FOO = 5; // ... (int) FOO = 6; // Can make this compile 
根据平台的不同,如果常量被放置在只读段中,那么赋值可能在运行时仍然失败,并且根据C标准它是正式的未定义行为。
 就个人而言,对于整数常量,我总是使用enum的其他types的const ,我使用const除非我有一个非常好的理由不。 
从C编码器:
  const是一个简单的variables,其内容不能改变。 
 但是,# #define name value是一个预处理器命令,用valuereplacename所有实例。 
 例如,如果你#define defTest 5 ,那么你编译时,你的代码中所有的defTest实例将被replace为5 。 
理解#define和const指令之间的区别是非常重要的。
 const 
  const用于从被问询的types生成一个对象,一旦初始化,该对象将保持不变。 这意味着它是程序存储器中的一个对象,可以作为只读使用。 每次程序启动时都会生成该对象。 
 #define 
  #define用于简化代码的可读性和将来的修改。 当使用一个定义时,你只能掩盖一个名字后面的值。 因此,在使用矩形时,可以使用相应的值定义宽度和高度。 然后在代码中,它会更容易阅读,因为代替数字会有名字。 
如果以后你决定改变宽度的值,你只需要在定义中改变它,而不是在你的整个文件中进行无聊和危险的查找/replace。 编译时,预处理器将用代码中的值replace所有定义的名称。 因此,没有时间使用它们。
 除了其他人的评论之外,使用#define错误是非常难以debugging的,因为预处理器在编译器之前掌握了这些错误。 
 由于预处理器指令是皱眉,我build议使用const 。 您无法使用预处理器指定types,因为在编译之前会parsing预处理器指令。 那么,你可以,但是像这样: 
 #define DEFINE_INT(name,value) const int name = value; 
并将其用作
 DEFINE_INT(x,42) 
这将被编译器看作
 const int x = 42; 
首先,我发现它不可能使用#define定义常量的types,为什么呢?
你可以看到我的第一个片段。
其次,使用其中一个有什么好处?
 通常有一个const而不是预处理器指令有助于debugging,而不是在这种情况下(但仍然)。 
最后,哪种方式更有效率和/或更安全?
两者都是有效的。 我会说macros可能会更安全,因为它不能在运行时更改,而variables可以。
我曾经使用过#define来帮助创build更多的方法,如果我有类似的东西。
  // This method takes up to 4 numbers, we don't care what the method does with these numbers. void doSomeCalculationWithMultipleNumbers:(NSNumber *)num1 Number2:(NSNumber *)num2 Number3:(NSNumber *)num23 Number3:(NSNumber *)num3; 
但我也有一个方法,只需要3个数字和2个数字,而不是写两个新的方法,我将使用#define使用相同的,就像这样。
  #define doCalculationWithFourNumbers(num1, num2, num3, num4) \ doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), (num4)) #define doCalculationWithThreeNumbers(num1, num2, num3) \ doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), nil) #define doCalculationWithTwoNumbers(num1, num2) \ doSomeCalculationWithMultipleNumbers((num1), (num2), nil, nil) 
我认为这是一件非常酷的事情,我知道你可以直接使用这个方法,只在你不想要的空间中放入零,但是如果你正在build立一个库,它是非常有用的。 这也是如何
  NSLocalizedString(<#key#>, <#comment#>) NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>) NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>) 
完成。
而我不相信你可以用常量做到这一点。 但是常量比#define有更多的好处,就像你不能用#define指定一个types一样,因为它是一个在编译之前解决的预处理器指令,如果你在#define中遇到错误,那么它们就很难debugging常量。 两者都有好处和坏处,但我要说这一切都取决于程序员你决定使用哪一个。 我已经写了一个库,他们在使用#define做我已经显示和常量声明常量variables,我需要指定一个types。