#在Objective-C中定义vs常量
我是Objective-C新手,我对#在Objective-C中定义vs常量,objective-c,constants,c-preprocessor,Objective C,Constants,C Preprocessor,我是Objective-C新手,我对const和预处理指令#define有一些问题 首先,我发现不可能使用#define定义常量的类型。为什么呢 第二,使用其中一种方法比使用另一种方法有什么好处 最后,哪种方法更有效和/或更安全?由于不支持预处理器指令,我建议使用常量。不能使用预处理器指定类型,因为预处理器指令在编译之前已解析。好吧,你可以,但有点像: #define DEFINE_INT(name,value) const int name = value; 并将其用作 DEFINE_INT
const
和预处理指令#define
有一些问题
首先,我发现不可能使用#define
定义常量的类型。为什么呢
第二,使用其中一种方法比使用另一种方法有什么好处
最后,哪种方法更有效和/或更安全?由于不支持预处理器指令,我建议使用
常量。不能使用预处理器指定类型,因为预处理器指令在编译之前已解析。好吧,你可以,但有点像:
#define DEFINE_INT(name,value) const int name = value;
并将其用作
DEFINE_INT(x,42)
编译器会将其视为
const int x = 42;
首先,我发现不可能使用#define定义常量的类型,为什么
你可以看到我的第一个片段
第二,使用其中一种方法比使用另一种方法有什么好处
通常,使用const
代替预处理器指令有助于调试,在这种情况下没有那么多(但仍然如此)
最后,哪种方式更有效和/或更安全
两者都同样有效。我想说,宏可能更安全,因为它在运行时不能更改,而变量可以更改。来自C编码器:
const
只是一个内容无法更改的变量
#define name value
是一个预处理器命令,它将name
的所有实例替换为value
例如,如果您#定义defTest 5
,则编译时代码中的所有defTest
实例将替换为5
。除了其他人的注释,众所周知,使用#define
的错误很难调试,因为预处理器在编译器之前就掌握了这些错误。理解#define指令和const指令之间的区别是很重要的,这两条指令的意义不同
const
const
用于从请求的类型生成一个对象,一旦初始化,该对象将是常量。这意味着它是程序内存中的一个对象,可以用作只读。
每次启动程序时都会生成该对象
#定义
使用#define
以简化代码可读性和将来的修改。使用定义时,仅在名称后面屏蔽一个值。因此,使用矩形时,可以使用相应的值定义宽度和高度。然后在代码中,它将更容易阅读,因为将有名称而不是数字
如果以后决定更改宽度的值,则只需在“定义”中进行更改,而不必在整个文件中进行枯燥而危险的查找/替换。
编译时,预处理器将用代码中的值替换所有定义的名称。因此,使用它们不会浪费时间
首先,我发现不可能使用#define定义常量的类型,为什么
为什么是什么?这不是真的:
#define MY_INT_CONSTANT ((int) 12345)
第二,使用其中一种方法比使用另一种方法有什么好处
对#define
定义一个宏,该宏甚至在编译开始之前就被替换const
只是修改一个变量,这样当您试图更改它时,编译器将标记一个错误。在某些上下文中,您可以使用#define
,但不能使用常量(尽管我正在努力使用最新的叮当声找到一个)。从理论上讲,const
会占用可执行文件中的空间并需要对内存的引用,但实际上这并不重要,编译器可能会对此进行优化
const
s比#define
s对编译器和调试器更友好。在大多数情况下,这是在决定使用哪一个时应该考虑的首要问题。
只需考虑一个可以使用#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;
在标题中MY_INT_CONST
不能用作任何C文件中静态或全局作用域数组的大小,在中定义的除外
但是,对于整数常量,可以使用枚举
。事实上,苹果几乎总是这样做。这具有#define
s和const
s的所有优点,但仅适用于整数常量
// In a header
enum
{
MY_INT_CONST = 12345,
};
最后,哪种方式更有效和/或更安全
#define
在理论上更有效,尽管如我所说,现代编译器可能会确保两者之间没有什么区别#define
更安全,因为尝试分配给它总是一个编译器错误
#define FOO 5
// ....
FOO = 6; // Always a syntax error
const
s可能会被欺骗而被分配到,尽管编译器可能会发出警告:
const int FOO = 5;
// ...
(int) FOO = 6; // Can make this compile
根据平台的不同,如果常量被放置在只读段中,并且根据C标准它是官方未定义的行为,那么在运行时赋值仍然可能失败
就个人而言,对于整型常量,我总是使用enum
s来表示其他类型的常量,我使用const
,除非我有很好的理由不这样做。我以前使用过#define来帮助从一个方法中创建更多方法,就像我有类似的方法一样
// 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)
我认为这是一件非常酷的事情,我知道你可以直接使用这个方法,在你不想要的空间中放上nil,但是如果你正在构建一个库,它是非常有用的。还有这个我
NSLocalizedString(<#key#>, <#comment#>)
NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>)