跳转至

Objective-C

Objective-C简称Obj-C或者OC。 Obiective是面向对象的意思,所以Objective-C就是面向对象的C语言。

一、基礎

OC相对于C多了一些什么:

  • 在C的基础上新增了一小部分面向对象的语法
  • 将C复杂的、繁琐的的语法封装得更为简单
  • OC完全兼容C语言

OC程序的源文件后缀名是.m,m代表message代表OC中最重要的一个机制,消息机制。 int类型的返回值,代表程序的结束状态。 main 函数的参数仍然可以接受用户在运行程序的时候传递数据给程序,同样也可以不写。


import 指令

以#开头,所以是一个预处理指令。

作用:是#include指令的增强版,将文件的内容在预编译的时候拷贝到写指令的地方。

那么# import 增强在哪里呢?

同一个文件无论# import 多少次,都只会包含一次。而#include则单独做不到这点,必须配合条件编译指令来实现。

能做到这一点的简要原理是:# import 指令在包含文件的时候,底层会先判断这个文件是否被包含,如果被包含会略过,否则才会包含。


Foundation 框架

Foundation 是基础和基本的意思,言下之意在 Foundation 框架中提供了一些最基础的功能、输入和输出,还有一些数据类型。

所以# import < Foundation / Foundation .h>代表的是引入 Foundation 框架中的 Foundation .h头文件拷贝过来。

Foundation .h这个文件中包含了 Foundation 框架中的其他所有头文件,所以我们只要包含了这个文件就相当于包含了 Foundation 框架中所有的头文件, Foundation 框架中的所有函数和类就都可以直接使用了。


@autoreleasepool

这是自动释放池。


NSLog函数

作用:这个函数相当于C语言中的printf函数的增强版。向控制台输出信息。

语法格式:NSLog(@“格式控制字符串”,变量列表);

那么相对于printf函数,它增强的地方有哪些?

NSLog会输出一些调试的相关信息: 2020-07-18 16:18:44.675601+0800 First OC[1504:49178] Hello, World!

  • 会显示程序代码执行的时间
  • 会显示程序的名称
  • 会显示内存的进程编号和线程编号
  • 会自动换行
  • OC中新增了一些数据类型,这些新增的数据类型只能使用NSLog输出
  • NSLog的用法和printf基本相似,一样可以输出变量的值,并且占位符的用法也一样,但是要注意:NSLog函数的第一个参数前面必须要加一个@符号
  • 如果在字符串的末尾加了一个’\n’,那么NSLog函数的自动换行功能就会失效。

NSString

NSString类型的指针变量,专门用来存储OC字符串的地址。 这里要注意OC的字符串常量,必须要使用1个前缀@符号。

“Jack”,这是一个C语言的字符串 @“Jack”,这是一个OC的字符串常量

NSString类型的指针变量,只能存储OC字符串的地址。

语法格式:NSString *变量名 = @字符串常量;

注意:如果一个字符串常量前面没有@符号就表明这个字符串常量是一个C字符串,有@符号就是OC字符串常量。在使用NSString定义字符串时,必须要使用带有@前缀的字符串常量。NSString类型的指针变量,只能存储OC字符串。

所以,使用NSLog函数输出OC字符串指针时,要如何操作?

我们知道C语言中输出字符串可以用%s占位符来实现,而NSLog函数中输出OC字符串则需要使用%@占位符来实现。


NS前缀

由于OC是Steve Jobs在创建NeXT公司时倡导使用的编程工具,后来在NextStep中使用,再后来NextStep更名为Cocoa,由于Cocoa框架中很多源代码来自NextStep库中的 Foundation 和AppKit,工程师们选择使用NS来作为他们的类前缀,并沿用至今。

@符号

作用:将C字符串转换为OC字符串,OC中的绝大部份的关键字都是以@符号开头


OC中的注释

和C语言一样,OC的注释也分单行注释和多行注释,使用方法以及快捷方式都一样。


函数的定义和调用

OC中的函数定义和调用方法与C语言中函数方法一致!


二、OC与C的对比

OC程序的编译、链接和执行步骤和C语言基本一致:

以在终端中建立OC语言文件为例:

  1. 在当前工作文件夹下,用 touch 命令建立一个.m的OC语言程序文件
  2. 在.m文件中写上符合OC语法规范的源代码
  3. 使用cc -c命令将源代码编译为目标文件.o文件
  4. 使用cc命令将.o文件链接源文件

但这里与C语言略有不同,必须要告诉编译器去哪一个框架中找OC文件中使用的函数或者类。

所以命令如下:

cc xx.o - framework 框架名称

程序中用到了哪一个框架中的功能,就把框架名称替换为哪一个框架名字。

例如:

cc first.o - framework Foundation

链接成功后,就会生成一个a.out可执行文件了,执行这个文件即可。


三、数据类型

OC中支持C语言中的所有的数据类型。

基本数据类型 :

int double float char

构造类型:

数组 结构体 枚举

指针类型:

int* double* float * char*

空类型:

void

自定义类型:

typedef

OC支持以上所有类型

另外,OC还建立了一些新的数据类型:

BOOL类型

可以存储YES或者NO中的任意一个数据(YES和NO都是大写的)

一般情况下BOOL类型的变量用来存储条件表达式的结果。如果条件表达式成立就是YES,条件表达式不成立就是NO。

BOOL类型的本质是typedef signed char BOOL

实际上BOOL类型的变量就是一个有符号的char变量

进一步查看其定义内容会发现:

#define YES ((BOOL)1)
#define NO ((BOOL)0)
所以我们得知,YES实际上就时1,NO实际上就是0。

Boolean类型

可以存储true或者false中的任意一个数据。

一般情况下Boolean类型的变量用来存储条件表达式的结果。如果条件表达式成立就是true,条件表达式不成立就是false。

Boolean类型的本质是typedef unsigned char Boolean;

实际上Boolean类型的变量就是一个无符号的char变量。

进一步查看其定义内容会发现:

#define true 1
#define false 0

所以我们得知,true实际上就时1,false实际上就是0。

class 类

id 万能指针

nil、Nil、NULL、NSNull的區別

nil:指向Objective-C語言中物件的空指標,其定義值為(id)0。

Nil:指向Objective-C語言中類(Class)的空指標,其定義值為(Class)0。

NULL:指向C語言中的標準空指標,其定義值為(void *)0。

NSNull:在Objective-C語言的集合物件中,表示空值的物件,其定義值為[NSNull null]。[NSNull null]是一個物件,用在不能使用nil的場合。

因為在NSArray和NSDictionary中nil有特殊的含義(表示列表結束),所以不能在集合中放入nil值。如要確實需要儲存一個表示“什麼都沒有”的值,可以使用NSNull類。例:[NSMutableArrayObj addObject:[NSNull null]];

若obj為nil:[obj message]將返回NO,而不是NSException。

若obj為NSNull:[obj message]將丟擲異常NSException。

正常來說 nil,它所指的是一個物件對象,而這個對象的指標指向空 Empty,而 Nil 則是用來區別所指向的對象是一個類別 Class 而非物件,NULL 則指的是任何指向空值的指標。

SEL 方法选择器

block 代码段


四、运算

OC支持C语言中的所有的运算符

+、-、*、/、&&、||等等全部都支持

OC支持C语言中的所有控制语句

if结构、switch-case结构、while循环等等全部都支持。

OC支持C语言中的全部的关键字

OC新增了一些关键字,OC新增的关键字绝大多数都是以@符号开头。例如:

@interface

@ implementation

@ public

OC函数的定义和调用与C语言完全一致


五、面向过程与面向对象

在编程领域

如果在解决一件事情的时候,每一个步骤都是我们自己亲自去一步步实现,那么解决问题的这种思路就叫做面向过程的解决思路。

如果在解决一件事情的时候,自己并不亲自去做每一件事,而是找一个专家来帮助我们做,这样解决问题的思路,我们称之为面向对象的解决思路。


六、代码世界的面向过程与面向对象

这两种方法的优缺点。

首先,C语言是一门面向过程的语言,有功能的概念,但是没有去做事的人的概念;

而OC事一门面向对象的语言。

面向过程的方法的缺点:后期的维护和修改很不方便,而面向对象的方法在后期维护和修改十分方便。


七、使用面向对象的思维解决问题

八、类与对象


九、类的定义

那么如何去定义一个类呢?

定义类的语法:

位置:直接写在源文件中,不要写在 main 函数中 语法:分两部分,一个是类的声明,另一个是类的实现。

类的声明:

@interface 类名 : NSObject
{
 这类事物具有的共同的特征将它们定义为变量
}
功能就是一个方法将方法的声明写在这里
@end

类的实现:

@implementation 类名
将方法的实现写在这里
@end

@interface Person : NSObject
{
 NSString *_name;
 int _age;
 float _height;
}

@end


@implementation Person

@end
  • 类必须要有声明和实现
  • 类名用你描述的事物的名称来命名就可以了,类名的每一个单词的首字母必须要以大写开头
  • 用来表示这类事物的共同特征的变量必须要定义在@interface的大括号中
  • 定义在大括号之中的用来表示这类事物共同的特征的变量,我们叫做属性、成员变量、实例变量或字段
  • 定义的属性的名称必须要以下划线开头,这是编程规范

十、类的对象的创建和使用

这里必须要事先声明,光是定义了类,类是无法直接使用的。如果非要使用的话,就必须要先找到这个类的一个具体存在,也就是找到这个类中的一个对象,才能具体使用。

类和对象的关系是:类中有的东西,这个类的对象也有,不会多也不会少。

如何创建一个类的对象?

语法:类名 *对象名 = [类名 new];

例子:Person *p1 = [Person new];

这表示根据Person这个类的模板,创建了一个对象的名字叫做p1。

p1对象的特点:

  • 可以直接使用
  • 类Person中定义的内容,这个对象p1中也有,不会多也不会少