Objective-C中一些 值得程序员注意的地方:
1.有关于BOOL陷井方面有如下方面:
关于BOOL条件语句中的比较最好是与NO的值来进行比较,因为BOOL的 YES与NO值只是约定,并且编译器将BOOL认作8位二进制数据。若是不小心将一个长于1字节的整型值赋值给BOOL变量,那么只有底位字节将会用做 BOOL的值,假设底位字节刚好为0的话,那么BOOL的值将会是0,即NO值,所以关于比较方面推荐用变量值与NO值进行比较。
2.Objective-C中一些基础的语法问题:(重要声明:Objective-C就是C,不是什么其他的语言)
NS****命名规则:简单来说就是以NS为前缀加上匈牙利命名法。
#import 在 Objective-C中的使用情况:#import在 Objective-C程序中相当于#include在C/C++中的用法,但是前者在功能上面与后者是有一定的区别,简单说一点:前者可保证头文件只被 包含一次,而不管此命令在那个文件中实际出现(使用)了多少次。在c语言中,程序员通常使用机遇#ifdef命令的方案来避免一个文件包含另一个文件,而 后者又包含第一个文件的情况,在objective-c中,程序员使用#import实现这个功能。
NSLog()和@”字符串”在objective-c中的使用情况:
NSLog()函数在Objective-C中的作用相当于Console、printf()在c/c++语言中的作用。NSLog()还有时间 戳、日期戳和自动添加换行符(‘\n’)等一些Console与printf()不具备的功能。在Objective-C中@符号是其在标准c语言基础上 添加的特性之一,”"双引号中的字符串前有一个@符号,这表示引用的字符串应该作为Cocoa的NSString元素来处理。
NSString的部分功能有:
a.告知其长度;b.将自身与其他字符串进行比较;c.将自身转换为整型值或者浮点值。
在Objective-C中多参数方法的简要介绍:
多参数方法需要抓住的一点是后面的参数都需要写上名字。
在 Objective-C中加号、减号、中括号他们的意义与用法:
首先需要了解的一点是在 Objective-C中是没有public与private的概念的,即可以认为全部都是public。减号表示的是一个函数、方法、消息的开始。加号 则表示不需要创建一个类的实例,其他类就可以直接调用这个类中的函数(也可以说加号表示静态的成员函数)。中括号在 Objective-C中表示方法的调用(通常在 Objective-C中都是说”消息”)。下面一段转换关系就可以清楚的搞懂中括号的使用了:[[[MyCalss alloc] init:[foo bar]] autorelease]; 其转换为C#或者Java的语法如:MyCalss.alloc().init(foo.bar()).autorelease(); 这段转换关系非常的重要。
最后关于部分重要东西及个别问题的介绍:
1.id:
Objective-C有一种比较特殊的数据类型是id,可以理解为”随便”。等价于c语言中的void *;在Objective-C里一切数据都是以指针的形式保存,你获取到的就是这个对象在内存的位置,而id就是你知道的这个位置。
2.同一个数组可以保存不同的对象:
在Objective-C中数组(NSArray)里面可以保存各种不同的对象,通过以下例子来表示:{myArray<—|0: (float)234.33f 1:@”要玩娱乐” 2:(NSImage *) (图片资源) 3:@”世纪大光棍”}以上这个数组包含了4个元素,分别是浮点数、字符串以及图片。
3.BOOL、YES、NO:
在Objective-C中通常把YES等价于C#、Java、C、C++中的true,把NO等价于false,而实际上YES为1,NO为0,BOOL本身是一个char型数据(编译器认作为8位二进制数据)。
4.IBOutlet、IBAction是什么东西,为什么总能看见:
在语法中IBOutlet、IBAction没有太大作用,若是希望在Interface Builder中能看到这个控件对象,那么在定义的时候前面加上(IBOutlet),在IB里面就能看到这个对象outlet,如果希望在 Interface Builder里控制某个对象执行某些动作,就在方法前面加上(IBAction).实际上IBOutlet、IBAction就跟void是一样的。
5.nil的意义是什么:
在Objective-C里NULL(空)就是用nil来表示,nil表示空指针。
6.@”字符串”与”字符串”有什么不同或者区别:
“字符串”是C的字符串,@”字符串”是把C的字符串转换成NSString的一个简写.在需要NSString的地方才需要这个转化,例 如:NSLog里面.在需要C string的地方,还是用”字符串”的形式.另外,@”"这个转换是不支持中文的,例如NSLog(@”字符串”);是一定输出不了中文的.
3.函数原型和声明方式:
首先:先行下短线—即是“减号”,每种方法的名称、方法的返回值的类型和某些参数。先行短线后面接着就是返回值.
中缀符:Objective-C中有一种名为中缀符(infix natation)的语法技术,方法的名称及其参数都是合在一起的.如:可以这样调用带一个参数的方法:[circle setFillColor:kRedColor];带两个参数的方法调用如下:[textThing setStringValue:@"hello there"color: kBlueColor];setStringValue:和color:实际上是参数的名称(实际上是方法名称的一部分,后面在详细介 绍),@”hello there”和BlueColor是被传递的参数.
冒号:有参数的方法时通常是方法的名称结尾处是冒号,冒号之后紧接着就是这个参数类型及其参数名.冒号之后的圆括弧中是参数的类型.在无参数的方法 中在方法的名称结尾处通常是不需要添加冒号的而是分号.这里是非常需要注意的,有时候就是因为在没参数的方法后面加上了冒号而导致程序出现了错误信息是没 有意义的初级错误.
总结出以下情况为函数原型及声明的一般形式: - (方法的类型) 方法的名称: (参数的类型) 参数的名称; 或者是: – (方法的类型) 方法的名称;
最后:声明完成后必须在最后一句加上@end来告诉编译器类的声明已经完成.这也是很重要的一处基础.
4.实现代码的指令及需要注意的地方:
编译器同过@implementation这个指令来为某个类提供代码,类名出现在@implementation之后,该行的结尾处没有分号,因为在 Objective-C编译器指令后不必使用分号.在@implementation指令中各个方法的定义,不必按照在@interface指令中的顺序 出现,甚至可以在@implementation中定义那些在@interface中没有相应声明的方法。可以把他们(这里的他们是指的是:在 @interface中没有相应声明的方法)看成私有的方法,仅在类的实现中使用。在这里有一点需要注意:在Objective-C中是不存在真正的私有 方法.也就是说单独在@implementation指令中定义的方法是能从外部进行访问的,这算是Objective-C动态本质的副作用.传递隐藏的 参数是另一种间接操作的事例.Objective-C运行时(runtime)可以将不同的对象当成隐藏的self参数传递,所以哪些对象的实例变量发生 更改时,运行时也可以进行相应的更改.
说明:用户运行应用程序时,Objective-C运行时是支持这下应用程序(包括我们自己的应用程序)的代码块,运行时执行非常重要的任务,如向对象发送消息和传递参数.
5.实例化对象:
Shapes-Object中最后的、非常关键过程,在该过程中,我们创建形状对象,例如红色的圆形和绿色的矩形,这个过程的专业术语就叫做实例化 (instantiation).实例化对象时,需要分配内存,然后这些内存被初始化并保存一些有用的默认值,这些值不同于你在 获得新分配的内存时得到的随机值,内存分配和初始化完成后,就闯将了一个新的对象实例.这里有一点需要注意:由于对象的局部变量特定于该对象的实例,因此 我们称它们为实例变量,通常简写为ivars.
为了创建新对象,我们需要向相应的类发送new消息,因此接收并处理完new消息后,我们就会得到一个可以使用的新对象实例.
Objective-C有一个极好的特性,你可以把类当成对象来向类发送消息,这种便捷的行为不局限于某个特定的对象,而是对全体类都通用,这种消 息通常用在创建新对象时,如果需要创建新的circle对象,请求Circle类创建新对象比请求某个现有的circle对象更合适一些.
第4章节:
1.继承:~~@interface Circle: NSObject~~冒号后的标识是需要继承的类,因为可以从非类中继承对象.Cocoa,NSObject继承对象,因为NSObject提供了大量有 用的特性(当继承一个已继承自NSOvhect的类时,你也能获取这些特性).Objective-C中继承不支持多继承,想在Objective-C中 获得多继承的优点,那么就要使用Objective-C的其他特性,如:分类和协议,在本书12、13章有介绍.
2.重构:移动和简化代码的方式称为重构,这在OOP社区中是一个非常时尚的话题.进行重构时,你通过移动某些代码来改进程序的架构,正如我们在这 里把程序中重复代码删除,而不改变代码的行为或运行结果一样,通常的开发周期包括想代码中添加某些特性,然后通过重构删除所有的重复的代码.通常,在面向 对象的程序中添加某些新特性后,程序反而变得更简单,你可能对此觉得很奇怪,这就想我们添加了Shapes类后所出现的情况.
说明:因 为继承在子类和超类只见建立了一种”is a”(是一个)关系,所以NSObjec的实例变量称为isa.即Rectangle是一种Shape,Circle是一种Shape,使用Shape的 代码也可以使用Rectangle或Circle来代替.使用更具体种类的对象(Rectangle或Circle)代替一般类型(Shape),这种能 力称为多态性(polymorphism),它在希腊语中形象地表示”很多形状”.
小心易碎:编译器使用”基地址加偏移”机制实现奇妙的功能.给定的对象基地址,是指第一个实例变量的首个字节在内存中的位置.通过在该地址加上偏移 地址,编译器就可以查找其他实例变量的位置.如:如果圆角矩形对象的基地址是0×1000,则isa实例变量的地址是0×1000+0,即位于 0×1000位置,isa的值占4个字节,因此,下一个实例变量fillColor的起始地址位于4个偏移地址之后,即位于0×1000+4位置,或写作 0×1004,,每个实例变量与对象的基地址都有一个偏移位置.如果访问方法中的fillColor实例变量,编译器生成代码并得到存储self的位置 值,然后加上偏移值(在本例中为4),得到指向存储变量值的位置.随着时间的推移,这也回产生一些问题,现在,在编译器生成的程序中,这些偏移位置是通过 硬编码实现的.尽管苹果公司的工程师希望向NSObject中添加其他的实例变量,但他们无法做到,因为这样做会改变所有实例变量的偏移位置.这被称为脆 弱的基类问题(fragile base class problem).通过在Leopard中引入新的64位Objective-C运行(它使用间接寻址方式确定变量的位置),苹果公司解决了这个问题.
3.重写方法:有时候为了在类中引入某个独特的特性,需要添加新方法.还有时候可能需要替换或增强由这个新类的某个超类所定义的现有方法.(使某方法为空,当方法中的子类都各自实现了自己的功能方法时,就说方法实现了重写).涉及关键字有:super(超类)。
说明一点:重写方法时,调用超类方法总是一个不错的选择,这样可以实现更多的功能.通过用调用super来实现机会,这样可以 保证能够获得方法的所有特性。
|
|