Objective-C 语法 3
类的深入研究和分类
一、分类
(一)分类的基本知识
概念:Category 分类是OC特有的语言,依赖于类。
分类的作用:在不改变原来的类内容的基础上,为类增加一些方法。
添加一个分类:
文件结构图:
在分类中添加一个方法
Study方法的实现
测试程序:
(二)分类的使用注意
- 分类只能增加方法(包括类方法和对象方法),不能增加成员变量;
- 在分类方法的实现中可以访问原来类中的成员变量;
- 分类中可以重新实现原来类中的方法,但是会覆盖掉原来的方法,导致原来的方法无法再使用(警告);
- 方法调用的优先级:分类->原来的类->父类,若包含有多个分类,则最后参与编译的分类优先;
- 在很多的情况下,往往是给系统自带的类添加分类,如NSObject和NSString,因为有的时候,系统类可能并不能满足我们的要求。
- 在大规模的应用中,通常把相应的功能写成一个分类,可以有无限个分类,对原有类进行扩充,一般分模块写,一个模块一个分类。
(三)分类编程练习
- 给NSString类增加一个类方法,计算某个字符串对象中阿拉伯数字的个数;
- 给NSString类增加一个对象方法,计算当前字符串对象中阿拉伯数字的个数;
分类中方法的声明
分类中方法的实现
测试程序:
二、类的深入研究
(一)类的本质
类本身也是一个对象,是class类型的对象,简称“类对象”。
Class类型的定义:
Typedef struct obj class *class;
类名就代表着类对象,每个类只有一个类对象。
利用 class 创建 Person类
利用 Person 创建 Person 类型的对象
Person *p = [[Person alloc] init];
获取内存中的类对象有两种方法:
(1)class c=[p class];//指向类的对象的指针调用class方法
(2)Class c1=[Person class];//使用类名调用class方法
注意:c和c1打印出来的地址相同,class c2=[p class];可以证明所有的对象共用一个类方法。
( 二)类的加载和初始化
测试程序:
- 当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只会调用一次;
- 当第一次使用某个类时,就会调用当前类的+initialize方法;
- 先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法,最后调用分类的+load方法),先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)。
- 注意:在初始化的时候,如果在分类中重写了+initialize方法,则会覆盖掉父类的。
- 重写+initialize方法可以监听类的使用情况。
description方法和sel
一、description方法
Description方法包括类方法和对象方法。(NSObject类所包含)
(一)基本知
使用NSLog和@%输出某个对象时,会调用对象的description方法,并拿到返回值进行输出。
使用NSLog和@%输出某个对象时,会调用类对象的description方法,并拿到返回值进行输出,把整个对象一次性打印出来,打印对象使用%@。
使用@%打印对象如(“@%”,P)默认打印输出为<类名:内存地址]] >,虽然字符串也是对象,但字符串在使用@%打印时情况特殊。
那么应该怎么实现打印对象的所有属性呢?在类的实现中重写description方法。
(二)实现打印对象的所有属性
(三)区别
(四)打印相关补充
二、SEL
SEL:全称Selector 表示方法的存储位置。
方法在内存中是怎么存储的?
寻找方法的过程:
- 首先把test这个方法名包装成sel类型的数据;
- 根据SEL数据找到对应的方法地址;
- 根据方法地址调用相应的方法。
- 注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。
关于_cmd:每个方法的内部都有一个-cmd,代表着当前方法。
注意:SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。
BLOCK和协议
一、BOLCK
(一)简介
BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码。用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行。
BOLCK和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样。
标识符^
(二)基本使用
(1)定义BLOCK变量
(2)利用block封装代码
(3)Block访问外部变量
- Block内部可以访问外部变量;
- 默认情况下,Block内部不能修改外部的局部变量
- 给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。
(4)利用typedef定义block类型(和指向函数的指针很像)
二、Protocol(协议
(一)简介
- Protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现。
- 只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。
- 只要父类遵守了某个协议,那么子类也遵守。
- Protocol声明的方法可以让任何类去实现,protocol就是协议。
- OC不能继承多个类(单继承)但是能够遵守多个协议。继承(:),遵守协议(< >)
- 基协议:是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
- 协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明。
(二)基本使用
创建一个协议
遵守协议
完成协议中声明的方法的实现
测试程序
1. 协议的定义
2. 如何遵守协议
类遵守协议
协议遵守协议
3. 协议方法声明中的关键字
(1)required (默认)要求实现,若没有实现则警告但不报错
(2)Optional 不要求实现
4. 定义变量时遵守协议的限制
5. Property中声明的属性也可以做遵守协议的限制
6. 补充知识:
协议本身写在.h头文件中,但也可以定义在任何地方。当这个协议只有这个类使用遵守时,一般把协议写在这个类里边,当这个协议需要多个类去实现时,就写在外边单独的文件中。
Foundation框架—结构体
一、基本知识
Foundation—基础框架。框架中包含了很多开发中常用的数据类型,如结构体,枚举,类等,是其他ios框架的基础。
如果要想使用foundation框架中的数据类型,那么包含它的主头文件就可以了。
即#import<foundation/foundation.h>
补充:core foundation框架相对底层,里面的代码几乎都是c语言的,而foundation中是OC的。
二、常用的结构体介绍及简单使用
常用的结构体:
(一)NSRang的基本使用
创建变量
(二)NSPoint/CGPoint的使用
(三)NSSize/CGSize的使用
(四)NSRect/CGRect的使用
常规的使用方式:
在开发中,想要验证结构体中属性的值,应该如何打印?
利用框架函数把相应的结构体转变成字符串,再直接打印字符串即可
(五)Foundation框架中一些经常用到的结构体函数
补充1:导入框架 Build phase->link
补充2:ios中坐标原点在左上角。
Foundation框架—字符串
一、Foundation框架中一些常用的类
二、NSString和NSMutableString的使用与注意
(一)6种创建字符串的形式
(二)使用注意
(1)字符串的导入导出
(2)类方法
(三)NSMutableString的使用与注意
(四)URL补充内容
url:资源路径
格式:协议头:/路径
网络路径协议头:http
本地文件以file为协议头
ftp为协议头,说明资源是ftp服务器上的。
Foundation框架—集合
一、NSArray和NSMutableArray
(一)NSArray不可变数组
(1)NSArray的基本介绍
NSArray是OC中使用的数组,是面向对象的,以面向对象的形式操纵对象,是不可变数组。
C语言数组有一个缺点即数组中只能存放同种数据类型的元素。
OC数组只能存放OC对象,不能存放非OC对象,如int,结构体和枚举等。
(2)NSArray的创建
(3)NSArray的访问
(4)NSArray的遍历
数组的遍历有以下几种方式:
首先创建一个数组
第一种方法:使用for循环遍历
Block遍历的深入研究:
每拿到一个元素,就传递给obj,就会调用一次block,并且把当前的元素和索引位置当做参数传递给block。
注意1:break只使用在两种场合,即switch和循环结构中。
注意2:stop参数用来停止遍历,其值若为YES,则停止。
(二)NSMutableArray可变数组
(1)NSMutableArray的基本使用
注意:NSMutableArray 继承自 NSArray,几乎拥有 NSArray 的一切方法。
二、NSSet和NSMutableSet
(一)NSSet不可变集合
基本使用:
(二)NSMutableSet可变集合
基本使用:
(三)NSSet和NSArray的对比
(1)共同点:
- 都是集合,都能够存放多个对象
- 只能存放oc对象,不能存放非oc对象类型(如int等基本数据类型和结构体,枚举等)。
- 本身都不可变,都有一个可变的子类。
(2)不同点:
NSArray 有顺序,NSSet 没有顺序
三、NSDictionary 和 NSMutableDictionary
(一)NSDictionary 不可变字典
(1)介绍
现实中的字典:根据索引找到具体的内容
OC 中的 NSDictionary:根据 key 找到 value。里面存储的东西都是键值对。
(2)NSDictionary的创建
注意:快速创建字典是编译器特性。
(3)NSDictionary的访问
(4)NSDictionary的遍历
(二)NSMutableDictionary可变字典
(1)NSMutableDictionary的基本使用
(2)NSMutableDictionary的使用注意
注意:这种快速创建的方式只适用于不可变字典。