1

我正在用 BigNerdRanch 的书“Aaron Hillegass 的 Objective-C 编程”来研究 Objc,这件事一直让我感到困惑。

我知道编译器需要知道我在说什么类型的变量,所以我必须在赋值之前声明 var 类型。

int myNum = 10;

美好的。但是对于ObjC类,如果我必须在=之后声明指针类型,当我分配和初始化它时,声明指针类型的原因是什么?

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

显然 *dateFormatter 对象是 NSDateFormatter 的一个实例,我在分配中写了它。为什么我也必须在开头声明它?因为如果我尝试做类似的事情

NSString *timeZone = [NSTimeZone systemTimeZone];

Xcode 清楚地警告我使用“NSTimeZone *”类型的表达式初始化“NSString *”的不兼容指针类型。

我觉得我错过了什么。抱歉,如果这是一个愚蠢的问题,请尝试学习。

4

3 回答 3

3

这里真正的问题是“为什么我必须定义正确的指针类?”......

答案是:您可能还想在其他一些上下文中使用该变量。如果您[NSTimeZone systemTimeZone]直接发送消息,那么编译器可能能够推断出类型,但是如果您向变量发送消息呢?如果你选择较弱的类型

id tz = [NSTimeZone systemTimeZone];

那么,如果你在预期tz的地方使用 an ,编译器检查错误的机会NSTimeZone *就会比你将它声明为NSTimeZone *tz.

于 2013-10-04T11:05:53.077 回答
3

作为一个更清楚的例子,假设你有一个方法:

- (NSTimeZone *) userSpecifiedTimeZone {
    id timeZone = [NSTimeZone timeZoneWithAbbreviation:self.timeZoneName];
    if (timeZone == nil)
        timeZone = [NSTimeZone timeZoneWithName:self.timeZoneName];
    if (timeZone == nil)
        timeZone = self.timeZoneName;
    return timeZone;
}

看到错误了吗?

Xcode 不会捕获它,因为将任何对象分配给 type 的变量id,并id从返回类型为任何对象类型的方法返回一个,然后将其分配id给另一个id变量,或尝试发送消息是完全有效的在调用代码中。

只有在运行时,并且只有当用户输入虚假的时区名称,然后您尝试使用该时区名称(错误地作为此方法的结果返回)作为 NSTimeZone 对象。

与静态类型的版本相比:

- (NSTimeZone *) userSpecifiedTimeZone {
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:self.timeZoneName];
    if (timeZone == nil)
        timeZone = [NSTimeZone timeZoneWithName:self.timeZoneName];
    if (timeZone == nil)
        timeZone = self.timeZoneName; //Clang calls shenanigans here
    return timeZone;
}

Clang 正确地反对将 an 分配给NSString *类型为 as 的变量NSTimeZone *是可疑的。

您不必定义指针类,但是像上面显示的那样的错误的可能性是我们这样做的原因。

于 2013-10-04T20:28:03.927 回答
1

但是对于ObjC类,如果我必须在=之后声明指针类型,当我分配和初始化它时,声明指针类型的原因是什么?

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

您没有两次声明指针的类型。这个声明中有很多内容。第一次出现的“NSDateFormatter”告诉编译器 dataformatter 是指向这种类型对象的指针,而第二次出现的“NSDateFormatter”是调用 NSDateFormatter 类中的“alloc”方法。同一个词,两种完全不同的意思。

发生的第一件事是[NSDateFormatter alloc]在“NSDateFormatter”类中调用(类)方法“alloc”。这将返回一个 NSDateFormatter 对象的(空)实例,其中调用了方法“init”。然后将一个指向结果对象的指针存储在您的“dateFormatter”变量中,我们告诉编译器这是一个指向 NSDateFormatter 对象的指针。

可以这样想:

NSDateFormatter *dateFormatter;    Create a pointer to an NSDateFormatter object.
newDate = [NSDateFormatter alloc]; Create an empty NSDateFormatter object by calling the class method alloc in NSDateFormatter 
[newDate init];                    Initialise it by calling the onject's 'init' method
dateformatter = *newDate;          Assign a pointer to it to my variable.
于 2014-10-20T13:53:20.593 回答