我正在使用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 *'。
我觉得我错过了什么。对不起,如果这是一个愚蠢的问题,试着去学习。
答案 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.