我的Macbook什么时候到啊啊啊啊啊啊啊啊啊啊啊啊,没有Macbook连学习都成为了问题呜呜…
Objective的Hello World程序:
1 2 3 4 5 |
#import <Foundation/Foundation.h> int main(int argc, const char *argv[]){ NSLog(@"Hello, Objective-C"); return (0); } |
第二章 对C的扩展
注意需要保存成.m格式,该格式是OC的文件格式
其中,#import是Objective-C中的特定预编译指令,保证了所有的文件只被包含一次,相应的C语言中使用#ifdef的宏指令实现的
第一个Foundation表示的是框架名称,框架内的Foundation.h内部包含了Foundation中的所有的函数等,读取每个文件在XCode里面会采用预编译头文件来加快读取速度,当使用import来包含的时候会大大加快读取速度
NSLog是Cocoa的特性,包含NS前缀的都是Cocoa中的特性,在实际编程的时候不能使用NS前缀,因为可能与Cocoa中的重复,或者未来有可能会重复,该函数和C语言中的printf类似,都是采用printf的一个format格式,注意%s格式的话用的是char*类型
字符串前面带@表示这是一个NSSrting变量,自我感觉可以类比为C++中的string,可以将自身转换为整型或者浮点,另外有长度还有将自身与其他字符串比较等特性。
注意:当我们使用NSLog的时候,需要对所有的字符串都加上@,即所有的格式都需要是NSString,如果传入的是一个C语言的字符指针类型的话就会报一个error,XCode中可以通过设置成将警报作为错误来处理的方式来规范代码,在项目导航器(Project Navigator)然后选中TARGETS文字下的项目选项,然后找到Treat Warnings as Errors,将其值更改为Yes
另外Cocoa中的NSArray可以存放数组,NSDateFormatter可以方便用不同的方式来设置日期格式,NSThread可以提供多线程编程工具,NSSpeechSynthesizer可以帮助你听到语音
BOOL类型
OC中的BOOL类型可以简单的理解为一个unsigned char类型并且在头文件里面有宏定义#define YES 1 #define NO 0
所以这和C++里面的内容就不太一样了,我们判断两个数字是否相同就不能简单的使用return a-b;类似这样的代码,而要指定为YES NO,就是最好对BOOL类型进行直接的赋值,赋值为YES NO,不可以使用C语言中的赋值,即赋值为除了01别的值
要注意NSString本身也是一个指针,如下代码演示:
1 2 3 4 5 6 7 |
NSString *boolString(BOOL yesNo){ if(yesNo == NO){ return (@"NO"); }else { return (@"YES"); } } |
文件
文件读入读出和C语言类似,都是采用FILE*来输入输出
命令行参数和C语言类似,argv[1]代表输入的第一个参数…
在XCode中,设置命令行参数需要以下操作:Product -> Edit Scheme菜单中选择Arguments选项,然后点击Arguments Passed On Launch下的加号按钮,输入启动参数
日常吐槽:Macbook什么时候到啊
枚举
1 2 3 4 5 6 7 8 9 10 |
typedef enum{ kCircle, kRectangle, kEgg }ShapeType; typedef enum{ kRedColor, kGreenColor, kBlueColor }ShapeColor; |
结构体推荐使用
1 |
ShapeRect rect0 = {0, 0, 10, 30}; |
类似这样的方法来赋值,注意要按照顺序
另外使用了enum过后可以直接使用switch case 语句,比如上面的enum定义就可以使用这样的switch case语句
1 2 3 4 5 6 7 8 9 10 11 12 |
switch(shapes.type){ case kCircle: drawCircle(shapes.bounds, shapes.fillColor); break; case kRectangle: drawRectangle(shapes.bounds, shapes.fillColor); break; case kEgg: drawEgg(shapes.bounds, shapes.fillColor); break; } |
第三章 面向对象编程的基础知识
面向对象编程
使用方括号
1 |
[shape draw]; |
该语句代表我们向shape对象发送了一个draw消息,这个语句我们称之为发送消息
类的首字母要大写
消息是对象可以执行的操作,对象在接受消息后,将查询相应的类,以便找到正确的代码来运行。
在创建对象之前,我们需要定义接口,@interface表示告诉编译器一些有关于该类的信息
1 2 3 4 5 6 7 8 9 10 |
@interface Circle : NSObject { @private ShapeColor fillColor; ShapeRect bounds; } - (void) setFillColor: (ShapeColor) fillColor; - (void) setBounds: (ShapeRect) bounds; - (void) draw; @end // Circle |
第一行表示告诉编译器这个类名字叫Circle,继承于Cocoa中的NSObject类。该语句表明每个Circle类都是一个NSObject类,并且每一个Circle类都会继承NSObject类定义的所有行为。
花括号中的内容是定义数据成员,参考C++
下面的代码类似于C语言中的函数原型,列出了名称,返回值类型等
其中短线后面的是返回类型,后面跟着的是函数名称,冒号后面的是参数,括号里面代表参数类型,外面代表数据成员
中缀符
OC中的方法名称和参数是合在一起的,
例如:
[circle setFillColor: kRedColor];
带两个参数的调用如下所示:
[textThing setStringValue: @”hello there” color: kBlueColor];
方法的真正实现需要位于@implementation中,编写如下所示:
1 2 3 4 5 6 7 8 9 |
@implementation Circle - (void) setFillColor: (ShapeColor) c { fillColor = c; }//setFillColor - (void) setBounds: (ShapeRect) b { bounds = b; }//setBounds |
注意:在这里甚至可以定义未在@interface中声明的代码,这部分代码被视为私有内容
此处参数名称注意与上面不一样,为了区分数据成员和参数,所以我们要将参数重新命名
另外,参数在传递的时候会将隐藏的self参数传递进去
创建对象的时候我们需要向相应的类发送new消息,类似于:[circle new];这个操作会返回一个可以使用的实例
例如以下main函数,用于创建圆形,矩形和椭圆形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
int main (int argc,const char *argv[]){ id shapes[3]; ShapeRect rect0 = {0, 0, 10, 30}; shapes[0] = [Circle new]; [shapes[0] setBounds: rect0]; [shapes[0] setFillColor: kRedColor]; ShapeRect rect1 = {30, 40, 50, 60}; shapes[1] = [Rectangle new]; [shapes[1] setBounds: rect1]; [shapes[1] setFillColor: kGreenColor]; ShapeRect rect2 = {15, 19, 37, 29}; shapes[2] = [Egg new]; [shapes[2] setBounds: rect2]; [shapes[2] setFillColor: kBlueColor]; |
这里我们使用了消息请求来设置对象的值(即文中的setBounds和setFillColor)
开放/关闭原则
第四章 继承
继承
1 |
@interface Circle : NSObject |
1 2 3 4 5 6 7 8 9 10 11 12 |
@interface Shape : NSObject{ ShapeColor fillColor; ShapeRect bounds; } - (void) setFillColor:(ShapeColor)fillColor; - (void) setBounds:(ShapeRect) bounds; - (void) draw; @end // Shape @interface Circle : Shape @end // Circle @interface Rectangle : Shape @end // Rectangle |
1 2 3 4 5 6 7 8 9 10 11 12 |
@implementation Shape - (void) setFillColor: (ShapeColor) c { fillColor = c; }//setFillColor - (void) setBounds: (ShapeRect) b { bounds = b; }//setBounds - (void) draw { }//draw |
1 2 3 4 5 6 |
@implementation Circle - (void) draw { NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor)); }// draw @end Circle |
super关键词
1 2 3 4 5 6 7 8 9 10 11 |
@implementation Circle - (void)setFillColor:(ShapeColor)c { if( c == kRedColor) { c = kGreenColor; } [super setFillColor:c] }// setFillColor //and the rest of Circle @implementation //is unchanged @end // Circle |
第五章 复合
复合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@interface Car : NSObject { Pedal *pedal; Tire *tire[4]; } - (void) print; @end // Car @interface Tire : NSObject @end // Tire @implementation Tire - (NSString *)description{ return (@"I am a tire. I last a while"); }//description @end // Tire @interface Engine : NSObject @end // Engine @implementation Engine - (NSString *) description{ return (@"I am an engine. Vrooom!"); } |
NSLog自定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@implementation Car - (id) init { if (self = [super init]){ engine = [Engine new]; tire[0] = [Tire new]; tire[1] = [Tire new]; tire[2] = [Tire new]; tire[3] = [Tire new]; } return (self); }// init - (void) print { NSLog(@"%@", engine); NSLog(@"%@", tire[0]); NSLog(@"%@", tire[1]); NSLog(@"%@", tire[2]); NSLog(@"%@", tire[3]); }// print @end // car |
1 2 3 4 5 6 |
int main(int argc, const char *argv[]){ Car *car; car = [Car new]; [car print]; return (0); } |
存取
1 2 3 4 5 6 7 8 9 10 11 |
- (Engine *) engine { return (engine); } // engine - (void) setEngine: (Engine *) newEngine { engine = newEngine; } // setEngine Engine *engine = [Engine new]; [car setEngine: engine];// setter方法 NSLog(@"the car's engine is %@", [car engine]);//getter方法 |
0 条评论