为什么我必须定义指针的类?

时间:2013-10-04 10:57:40

标签: objective-c cocoa

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

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

int myNum = 10;

精细。但是当谈到ObjC类时,如果我必须在=之后声明它,当我分配并初始化它时,声明指针类型的原因是什么?

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

显然* dateFormatter对象是NSDateFormatter的一个istance,我在分配中写了它。为什么我也要在开头宣布它? 因为如果我尝试做像

这样的事情
NSString *timeZone = [NSTimeZone systemTimeZone];

Xcode清楚警告我'不兼容的指针类型初始化'NSString *',表达式为'NSTimeZone *'。

我觉得我错过了什么。对不起,如果这是一个愚蠢的问题,试着去学习。

3 个答案:

答案 0 :(得分:3)

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

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

id tz = [NSTimeZone systemTimeZone];

如果您使用tz预期NSTimeZone *而不是NSTimeZone *tz声明{{1}},那么编译器检查错误的机会就会少得多。

答案 1 :(得分: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不会捕获它,因为将任何对象分配给id类型的变量并从返回类型为任何对象类型的方法返回id是完全有效的,并且随后在调用代码中将id分配给另一个id变量,或尝试向其发送消息。

你会发现这个错误 - 如果你没有尽早用你自己的人眼看到它 - 仅在运行时,并且只有当用户输入一个虚假的时区名称,然后你尝试使用那个时区name(作为此方法的结果错误地返回)作为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;
}

正确判断将NSString *分配给键入为NSTimeZone *的变量的对象是可疑的。

你没有必须定义指针的类,但是对于像上面显示的那样的错误的潜力是我们这样做的原因。

答案 2 :(得分:1)

  

但是当谈到ObjC课程时,宣布这个课程的原因是什么   指针的类型,如果我必须在=之后声明它,当我   分配并初始化它?

     

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

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

首先发生的是[NSDateFormatter alloc],它在'NSDateFormatter'类中调用(class)方法'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.