一、基础语法
OC相对于C
a. 在C的基础上新增了面向对象的语言
b. 将C的复杂、繁琐的语法封装的更为简单
c. OC完全兼容C语言OC程序的源文件后缀名是.m m代表message 代表OC当中最重要的一个机制 消息机制
C程序的源文件的后缀名.cmain函数仍然是OC程序的入口和出口
int类型的返回值代表程序的结束状态
main函数的参数: 仍然可以接收用户在运行程序的时候传递数据给程序,
参数也可以不要#import指令
1). 以#号开头,是1个预处理指令
2). 作用: 是#include指令的增强版。将文件的内容在预编译的时候拷贝在写指令的地方
3). 增强: 同一个文件无论#import多少次,只会包含一次
如果#include指令要实现这个效果,就必须要配合条件编译指令来实现
而#import指令只需要直接包含就可以
4). 简要原理: #import指令在包含文件的时候,底层会先判断这个文件是否被包含,
如果被包含就会被略过,否则才会包含。框架
1). 是一个功能集 苹果或者第三方事先将一些程序在开发程序时经常要用到的功能事先写好
把这些功能封装在一个类或函数中,这些函数和类的集合就叫做框架。
有点像C语言的函数库2). Foundation框架
Foundation: 基础 基本. 这个框架当中提供了一些最基本的功能 输入输出, 数据类型Foundation.h 这个文件当中包含了Foundation包含了其他所有的头文件 只要包含Foundation.h就想当于包含了框架当中所有的头文件。
@autoreleasepool{} 自动释放池
代码写在这个大括号中NSLog函数
1). 作用: 是printf函数的增强版, 向控制台输出信息
2). 语法:
NSLog(@”格式控制字符串”, 变量列表);
最简单语法:
NSLog(@”要输出的信息”);
3). 增强:
a. 输出一些调试相关的信息
2020-07-01 12:40:05.175 Day01-OC基础用法 [792:213878] Hello,World
执行代码的时间 程序名称 792是进程编号,213878是线程编号 输出信息
可用于测试程序执行时间
b. 会自动换行
c. OC新增的数据类型的变量的值只能使用NSLog函数输出
4). 用法和printf函数差不多
5). 使用注意:
a. NSLog函数的第一个参数前面必须要加1个@符号
b. 如果在字符串的末尾加1个’\n’代表换行, 那么函数的自动换行会失效字符串
1). C语言的字符串的存储方式
a. 使用字符数组存储
b. 使用字符指针
2). OC当中更为好用的存储字符串的类型. NSString
NSString类型的指针变量专门用来存储OC字符串的地址
3). OC的字符串必须要使用1个前缀@符号
“jack” 是一个C语言的字符串
@”jack” 是一个OC的字符串常量
NSString 类型的指针变量只能存储OC字符串的地址
4). 使用
NSString *str = @”jack”;
5). 总结
a. 在OC中专门设计了1个NSString类型来存储字符串
b. 字符串分为C字符串和OC字符串
c. 区分: 是否有@前缀
6). 注意
a. NSLog函数的第1个参数是OC字符串
b. 输出
NSString *str = @”jack”;
NSLog(str);
c. 如果要使用NSLog函数中的占位符输出字符串的值, 应使用”%@”NS前缀
NextStep –> Cocoa –> Foundation框架之中@符号
1). 将C字符串转换为OC字符串
“jack” ->> @”jack”
2). OC当中的绝大部分关键字是以@符号开头注释:
和C语言的注释一模一样, 分为单行注释和多行注释函数的定义和调用: 与C语言的函数调用是一样的
void test();// 声明
void test(){// 实现}
二、OC与C的对比
OC程序的编译、链接、执行
1). 在.m文件中写上符合OC程序的源代码
2). 使用编译器将源代码编译为目标文件
cc -c xx.m
a. 预处理
b. 检查语法
c. 编译
3). 链接
cc xx.o
如果程序中使用到了框架中的函数或者类,那么在链接时就必须要告诉编译器去哪里找Foundation框架
cc xx.o -framework Foundation
4). 链接成功后, 就会生成1个a.out可执行文件, 使用”./a.out”执行OC程序和C程序各个阶段的后缀名对比
源文件 目标文件 可执行文件
C .m .o .out
OC .m .o .out
- OC中的数据类型
1). OC中支持C语言中的所有的数据类型
a. 基本数据类型
int double float char
b. 构造类型
数组 结构体 枚举
c. 指针类型
d. 空类型
e. typedef自定义类型
2). BOOL 类型
BOOL b1;
a. 可以存储YES或者NO中的任意1个数据(必须是大写).
b. 一般情况下BOOL类型的变量用来存储条件表达式的结果.
c. BOOL的本质
typedef signed char BOOL;
实际上BOOL类型的变量是1个有符号的char变量
#define YES ((BOOL)1)
#define NO ((BOOL)0)
4). Boolean
a. Boolean类型的变量可以存储true或者false
b. 一般情况下BOOL类型的变量用来存储条件表达式的结果.
c. 本质
typedef unsigned char Boolean;
#define true 1
#define false 0
5). class 类型. 类
6). id 类型 万能指针.
7). nil 与 null 差不多
8). SEL 方法选择器
9). block 代码段
三、 面向过程与面向对象
OC是在C的基础之上
1). 将C复杂的语法封装的更为简单
2). 在C语言的基础之上新增了一小部分的面向对象的语法实现需求之一:
1). 要把大象放进冰箱应该怎么办?
a. 打开冰箱门
b. 把冰箱放进去
c. 把冰箱门关上2). 买电脑的需求的实现方式:
a. 根据自己的需求和预算确定买的电脑型号
10000 iOS开发
b. 在网上查资料 确定型号
rMMP 9288
c. 去到数码产品中心
d. 找到Apple专卖店
e. 砍价 成交
f. 回家3). 更好的方式:
a. 自己做
强调的是过程, 步骤. 我是主角
b. 别人做
强调的比人. 我是指挥者面向过程: 如果解决1件事情的时候,每一件事情都是我们亲自去一步步实现
面向对象: 如果解决1件事情的时候,自己不去做,而是专门找一个人去做代码世界的面向过程与面向对象.
1). 面向过程
在遇到1个需求的时候,每个步骤都是自己亲自写代码完成
2). 面向对象
在遇到1个需求的时候,而是找一个专门做这件事的人面向对象和面向过程优缺点
C语言是一门面向过程的语言. 有功能的概念, 但是没有人的概念.
OC语言是一门面向对象的语言.面向过程解决问题的缺点: 后期维护和修改不方便.
面向对象解决问题的优点: 后期维护和修改方便.如何使用面向对象设计程序
当遇到一个需求的时候,不要亲自去实现.
1). 先看看有没有现成的框架做这件事
2). 如果没有,就自己实现对象: 现实生活中的一个具体存在, 看得见、摸得着,拿过来可以直接使用
类: 是对一群具有相同特征或者行为的事物的统称.抽象的,不能直接使用.
类和对象之间的关系
四、 类与对象
请问先有类还是先有对象
1). 现实角度 一定是先有对象再有类
2). 代码角度 一定是先有类再有对象类的作用: 描述一群具有相同特征和行为的事物
如何定义类
1). 类的三要素: 类名/特征/行为
2). 定义类的语法
a. 位置. 直接写在源文件中
b. 类的定义分为两部分
–> 类的声明
@interface 类名 : NSObject
{
这类事物具有的共同特征, 将他们定义为变量
}
功能就是方法,将声明写在这里
@end
–> 类的实现
@implementation 类名
将方法的实现写在这里
@end
3). 注意
a. 类必须要有声明和实现
b. 类名用你描述事物的名称来命名.
类名的每个单词单词首字母必须要大写.
c. 用来表示这类事物共同特征的变量必须要定义在@interface中的大括号中
d. 定义在大括号用来表示类事物共同特征的变量叫属性、成员变量、实例变量、字段…
e. 属性名必须要以下划线开头示例:
// 声明 @interface Person : NSObject { NSString *_name; int _age; float _height; } @end // 实现 @implementation Person @end
类是无法直接使用的. 如果非要使用这个类,必须要先找到这个类的具体存在
1). 如何创建一个类的对象
语法: 类名 *对象名 = [类名 new];
Person *p1 = [Person new];//创建Person对象
p1对象的特点:
->> 可以直接使用
->> 类定定义的东西, 对象都有如何使用对象
1). 如何访问对象的属性:
a. 默认情况下,对象的属型是不允许被外界直接访问的
如果允许对象的属性可以被外界访问,声明属性时加@public关键字
b. 访问对象的属性的方式
对象名->属性名 = 值;
对象名->属性名;
(对象名).属性名 = 值;
(对象名).属性名示例:
// 声明 @interface Person : NSObject { @public NSString *_name; int _age; float _height; } @end // 实现 @implementation Person @end // 使用-- 平时建议使用这种形式 Person *p1 = [Person new]; p1->_name = @"jack"; p1->_age = 19; p1->_height = 178.5f; NSLog(@"p1对象的_name属性的值是%@", p1->_name); (*p1)._name = @"jack"; (*p1)._age = 19; (*p1)._height = 178.5f;
方法的声明和调用
// 声明 @interface Person : NSObject { 属性: 类的特征 } 方法: 类的功能 @end // 实现 @implementation Person 方法实现 @end
无参数方法声明
1). 声明
a. 位置: 在@interface的大括号的外面
b. 语法:
– (返回值类型) 方法名称;
– (void)run;
表示声明了1个无返回值的并且无参数的方法, 名字叫run
2). 实现
a. 位置: 在@implementation之中实现
b. 语法: 将方法声明拷贝到@implementation中,去掉分号追加大括号3). 调用
a. 方法是无法直接调用的, 必须要创建对象
b. 调用对象的方法.
[对象名 方法名];示例:
// 声明 @interface Person : NSObject{ NSString *_name; int _age; } - (void)run; @end // 实现 @implementation Person - (void)run{ NSLog(@"Hello,World!"); } @end // 调用 Person *p1 = [Person new]; [p1 run];
带1个参数的方法
1). 声明
a. 位置: 在@interface的大括号的外面
b. 语法:
– (返回值类型) 方法名称:(参数的类型)形参名称;
– (void)eat:(NSString *)foodName;
表示声明了1个无返回值的含有一个参数的方法, 名字叫”eat:”,有一个参数类型是NSString *类型,参数的名字叫foodName
2). 实现
a. 位置: 在@implementation之中实现
b. 语法: 将方法声明拷贝到@implementation中,去掉分号追加大括号3). 调用
a. 方法是无法直接调用的, 必须要创建对象
b. 调用对象的方法.
[对象名 方法名:实参];示例:
// 声明 @interface Person : NSObject{ NSString *_name; int _age; } - (void)run; - (void)eat:(NSString *)foodName; @end // 实现 @implementation Person - (void)run{ NSLog(@"Hello,World!"); } - (void)eat:(NSString *)foodName{ NSLog(@"给我的%@真好吃",foodName); } @end // 调用 Person *p1 = [Person new]; [p1 run]; [p1 eat:@"红烧排骨"];
方法头中的数据类型都要用1个小括号括起来.
- (返回值类型)方法名称:(参数类型)参数名称;
带多个参数的方法
1). 声明
a. 位置: 在@interface的大括号的外面
b. 语法:
– (返回值类型) 方法名称:(参数的类型)参数名称1 :(参数类型)参数名称2.。。;
– (int)sum:(int)num1 :(int)num2;
表示声明了1个返回值为int的含有两个参数的方法, 名字叫”sum: :”,有两个参数 参数类型都是int类型, 参数名称叫做num1,num2
2). 实现
a. 位置: 在@implementation之中实现
b. 语法: 将方法声明拷贝到@implementation中,去掉分号追加大括号3). 调用
a. 方法是无法直接调用的, 必须要创建对象
b. 调用对象的方法.
[对象名 方法名:实参1 :实参2];示例:
// 声明 @interface Person : NSObject{ NSString *_name; int _age; } - (void)run; - (void)eat:(NSString *)foodName; - (int)sum:(int)num1 :(int)num2; @end // 实现 @implementation Person - (void)run{ NSLog(@"Hello,World!"); } - (void)eat:(NSString *)foodName{ NSLog(@"给我的%@真好吃",foodName); } - (int)sum:(int)num1 :(int)num2{ int num3 = num1 + num2; return num3; } @end // 调用 Person *p1 = [Person new]; [p1 run]; [p1 eat:@"红烧排骨"]; int sum = [p1 sum:10 :20]; NSLog(@"sum = %d",sum);
带参数的方法声明的规范:–提高阅读性.
1). 如果方法只有1个参数: 要去最好这个方法的名字叫做xxxWith:
– (void)eatWithFood:(NSString *)foodName;
2). 如果方法有多个参数: 方法名With: (参数类型)参数名称1 and:(参数类型)参数名称2;
– (int)sum:(int)num1 and:(int)num2;
3). 更详细的写法
方法名With参数1:(参数类型)参数名称1 and参数2:(参数类型)参数名称2…
- 其他使用注意
1). 快捷
a. 快速实现方法: – -> 空格 方法名
b. 快速创建对象: 对象 new -> 右括号(自动补齐)