OC即Objective-C,OC是C语言的扩展,其是OS X,IOS上的应用开发语言。本系列主要讲述,学习OC的心得与经验。本博文假设读者已经对C语言有了掌握,且对C++有一定的了解,为了更好的理解语言的相通之处,还有在设计上的各种神通,将以C++为参考进行对比。「此系列博文需要基础」
一、启程
下面还是以一个程序开始。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
NSLog(@"Hello, World!");
return 0;
}
OC的IDE为Xcode,在第一次创建程序的时候,就会出现上述代码。
#import
如果学习过Java,那么对这个关键字就会很熟悉,但是在这里还是和C语言一样,只是对头文件进行包含,但是其增加了判断头文件是否重复包含的功能。可以理解为将#include进行了一层封装。
Foundation
Foundation,基础的意思,在这里称之为Foundation框架,为了便于理解,可以对比C++的STL,它是很多头文件的一个集合,除了框架,大佬们还将框架整理成一个框架集,于是Cocoa框架集出现了,Foundation框架是Cocoa的组成部分之一。《Foundation.h》这个头文件的位置如下,每次都创建程序的时候,系统都会自动的带上这个头文件,至于为什么,感兴趣的同学根据下面的路径去找吧,该目录下第一个就是,会有惊喜的。
NSLog
main函数就介绍了,和C语言是一样的。这个NSLog和printf的作用是一样的,但是比printf强大。其也是支持格式输出的。列出如下和C语言不一样的,其余都是一样的。
%@,输出对象
%f 浮点/双字
%zu size_t
%e 浮点/双字 (科学计算)
%g 浮点/双字
%c 字符
%C unichar
%lld 64位长整数(long long)
%llu 无符64位长整数
%Lf 64位双字
为什么以NS为前缀?如果对OC的历史感兴趣的可以去百科找找,这里不细说,仅提供大概的描述。这是因为Cocoa的前身名叫NextStep。为了避免名称冲突,于是只要是属于或者说是Cocoa框架集提供的都是以NS为前缀。为什么都改名了还以NS为开头,可以理解为你我的阑尾,属于历史遗留问题。
说完历史,说一下为什么有一个@,这是因为其参数是一个NSString,就是Cocoa提供的字符串对象。因此输出时都是通过格式构造出一个NSString对象。
(NSString的对象都是以@开头)
二、 类
有了C++基础,对于理解OC的类不是难事,后面的一些列特性都以C++中的一些语法为例子。对于OC来说,类的声明和实现是分开的。一般在头文件 .h 进行声明,.m文件中进行实现(C语言的源代码文件以.c为后缀,C++以.cpp)。语法如下:
/*.h文件*/
@interface 类名 : 父类
{
成员变量/属性
}
-(返回值) 方法名:(参数类型) 参数名;
+(返回值) 方法名:(参数类型) 参数名;
@end
/*.m文件*/
//实验一个.h文件是否可以有多个类
@@implementation Circle
-(返回值) 方法名:(参数类型) 参数名
{}
+(返回值) 方法名:(参数类型) 参数名
{}
@end
以interface来定义类,与implementation来实现类。与C++语法不同之处或者自己的特点就是:
- 每一个类都有一个父类,或者说是超类,第一个自定义的类都是NSObject,后续就会了解到NSObject其实是我们的根类。因此每时每刻都有继承。继承的语法和C++中不同的就是没有多继承,而且没有继承的那三个权限问题。
如果没有父类就会出现错误:Class ‘Test’ defined without specifying a base class
- 类声明时,其成员变量在花括号内。且关键字都是以@开始,结尾都是以end结尾,因此不存在用花括号来进行分割代码。
- 方法的定义格式与众不同,其冒号用来分割参数,注意其方法的特点还有如下的特征:
- 冒号也是方法名的一部分
- 多个参数的时候也是多个冒号,而且有如下花里胡哨的美好
-(void)setName:(NSString*) name AndAge : (int) age;
这个函数名就是 setName:AndAge : 这样的好处就是在传参的时候知道每个参数是干嘛的。
- 实现类的时候不要带后面的继承那一部分。
简单实现类的一般方法见上述,相对来说比较简单,但是对于C++来说,OC的面向对象会更纯粹一些,见后续。
三、 对象
OC在实例化对象的时候虽然也可以用new,其底层还是调用的alloc,init两个函数,因此,后续写代码直接调用这两个函数就好,不用new。
OC是完全兼容C的,因此写任何C代码都是没问题的,说这个的原因就是没法用OC写一个单独的函数,OC写成员函数是没有问题的。另外OC的代码在编译的时候还是转换成了C语言的代码,因此所谓兼容其实就是穿了衣服的C语言。
3.1 消息
先说一下OC的方法调用吧。OC的方法调用就不要用调用来说了,应该说是传递,因为在OC中,方法的调用过程称为消息传递过程。
[对象 消息] ----> [obj message](.m的后缀就是message)
[对象 方法]
这就是OC的方法调用/消息传递
3.2 对象
OC中的对象都是以指针的形式,例如:
NSString* str = [[NSString alloc] init];
上述的就是一个Cocoa提供的字符串类。至于为什么是指针对象,这就要说到OC对于对象模型的组织了(后话)。
因此我们后面创建对象都是以指针的形式创建
3.3 构造函数
上述的init就是构造函数,无参的够赞函数,类比C++中编译器默认生成的默认函数。如果要传参数怎么办?如下声明够赞函数:
(类名*)initWith:(类型)参数名 Withxxx:(类型)参数名;
- 类名*可以换成id,id是一个指向对象的指针,这是个万能指针,这是OC的新添加的一个数据类型
- 构造函数有返回值了,不像C++没有返回值,这个返回值是this指针,但是在OC中请写成self。
- Withxxx是一个描述,描述你这个参数的。带参数的构造函数就像一个普通的方法,只是返回值和作用比较特殊而已。
四、 后记
本系列博文主要是记录学习OC的路上,一些比较不同的地方,或者是难以理解的地方。因此阅读的时候需要一些基础。另外这只是本人的理解,如有不对的抵挡还望指正,以免误人子弟。
OC为什么要用指针来描述对象,而不是像C++一样创建的时候就自动调用构造函数然后创建好?请见后续内存管理章节。至于为什么说OC更为纯粹的面向对象,正式因为上述的原因吧。具体原因,请见下一站
博文示例代码【戳我进入】
最后用一个简单的猜拳游戏进行总结吧。
【戳我进入猜拳游戏源代码】