【问题标题】:Why Some Variables are Declared with an * Asterisk in Objective-C为什么某些变量在 Objective-C 中用 * 星号声明
【发布时间】:2021-01-23 23:42:50
【问题描述】:

我刚刚开始学习 Objective-C。我很困惑地看到某些类型的变量有时用 * 星号声明,而另一些则不是。例如,这些是用 * 标记的:

@property NSString *firstName;
NSString * mainString = @"Hello World!";
NSNumber *longNumber = @42l;
NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];

这些都不是:

int someInteger = 42;
NSInteger anInteger = 64;
id firstObject = @"someString";
NSRange substringRange = [mainString rangeOfString:@"long"];

我从 Apple 的文档中找到了这个解释:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW1

这两个属性都适用于 Objective-C 对象,因此它们使用星号表示它们是 C 指针。

但是这个解释太笼统和模糊,我无法理解这个概念。我知道type * 表示它是一个指针类型,并且这个类型存储了该类型的指针。但是为什么有些类型是用* 声明的,有些不是呢?

【问题讨论】:

  • 请注意,“*”来自 C 语言,而不是 Objective-C。正如 Rob 在他的回答中解释的那样,它的意思是“指向”。

标签: ios c objective-c


【解决方案1】:

int 类型不是对象。它是一种 C 语言的“原始数据类型”。您通常直接与原始 C 数据类型进行交互。例如,

int i = 0;   // it’s now `0`
i = 42;      // it’s now `42`

NSInteger 只是另一种原始数据类型long 的别名。 NSRange 是一个结构(因此,也不是一个对象),所以同样的规则适用。因此,对于与这些原始数据类型的基本交互,通常不需要 * 指针引用。 (实际上有时您还处理指向原始数据类型的指针,但这超出了本问题的范围。)

但是NSStringNSNumberNSArray都是对象,所以在声明它们时必须使用指针。


请注意,您已将 id 包含在未使用 * 的后一个列表中:

id firstObject = @"foo";

要非常小心。这实际上有点误导,因为firstObject 实际上指向@"someString" 的指针,NSString 对象。 id 是我们通常使用 * 声明指针的方式的一个例外,在 Objective-C is a Dynamic Language 中进行了讨论),“id 类型定义了一个通用对象指针。”

这类似于声明NSString 指针,但“你会丢失有关对象的编译时信息”。将id 指向NSString * 的指针与以下语法进行比较:

NSString *secondObject = @"bar";

后一个secondObjectNSString * 指针,但是因为我们将它显式声明为NSString * 指针,编译器知道您正在处理一个字符串(因此编译器可以对您后续使用的那个指针)。使用id,您不会享受这种编译时验证。

例如,这里有两次对两个 NSString 对象调用 removeObject 方法的无效尝试。 NSString 没有这种方法。 NSString * 参考提供了有用的编译时错误消息,id 无法提供给我们:

现在,如果您使用id 类型并尝试运行该代码,则当它尝试在firstObject 上调用removeObject 时会崩溃。但是,在可能的情况下,让编译器在编译时而不是在运行时告诉我们错误要好得多。

所以id 模式应该谨慎使用,只有当你真的需要Objective-C 的动态类型行为时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    相关资源
    最近更新 更多