黑马程序员——OC基础学习(五)---分类(Category),代码块Block和protocol代理设计模式_java partial oc category-程序员宅基地

技术标签: IOS 学习笔记  黑马程序员  分类Category  protocol代理设计模式  代码块Block  



------  <a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a> 期待与您交流! -------




     分类(Category),代码块Block和

     protocol代理设计模式学习总结



一.分类(Category)


  1.类别的概念

Category有很多种翻译: 分类\类别\类目 (一般叫分类)

Category是OC特有的语法, 其他语言没有的语法(类似于C#语言中的”扩展方法”和”partial”关键字)

  2.分类(Category)声明和实现 

(1)声明和实现一个类别

在.h文件中,声明类别:


@interface ClassName (CategoryName)NewMethod; //在类别中添加方法

                                             //不允许在类别中添加变量

@end 


说明:


声明类别格式

1)新添加的方法必须写在 @interface 与


2)ClassName 现有类的类名(要为哪个类扩展方法)


3)CategoryName 待声明的类别名称


4)NewMethod 新添加的方法


注意:不允许在声明类别的时候定义变量 


在.m文件中(也可以在.h中实现),实现类别:

@implementation ClassName(CategoryName)NewMethod

{

  ......

}

@end


说明:

  

    实现类别格式

1)新方法的实现必须写在@ implementation与@end之间


2)ClassName 现有类的类名


3)CategoryName 待声明的类别名称

4)NewMethod 新添加的方法的实现

 

注:也可通过图形界面生成类别


(2)调用类别中的方法

    与一般成员方法调用形式,完全一样需要包含类别的头文件 


  3.分类的使用注意事项 

1)分类只能增加方法,不能增加成员变量@property(可能编译不报错,但是运行有问题) 

2)分类可以访问原来类中的成员变量 

3)如果分类和原来类出现同名的方法,优先调用分类中的方法,原来类中的方法会被忽略 

注:分类的编译顺序为:最下面的是最后编译,当多个分类中有同名方法,则执行最后编译的文件方法 

  4.分类(Category)非正式协议

非正式协议就是给NSObject类创建的类目(分类)又叫做非正式协议, 

非正式协议一般不需要进行实现,一般在子类中进行方法的重写。 


  5.分类(Category)延展 

(1)类的延展的概念

延展类别又称为扩展(Extendsion)


Extension是Category的一个特例其名字为匿名(为空),并且新添加的方法一定要予以实现。(Category没有这个限制)


@interface Student ()


@end 

(2)延展的实现

通过延展来实现方法的私有,延展的头文件独立。这种方法不能实现真

正的方法私有,当在别的文件中引入延展的头文件,那么在这个文件中

定义的类的对象就可以直接调用在延展中定义所谓私有的方法 


// 对类的延展 - 隐藏方法 wrap的一种手段(非强制).h文件

@interface SceneManager ()
+ (void) wrap;

@end


.m类的实现文件中@implementation SceneManager+ (void) wrap {


NSLog(@"method of wrap");


}

@end



调用

[SceneManager wrap];
// 这里会抱一个警告:Class method of "+ wrap" not found
// 不过虽然是警告,不过运行是正常的,不过这么写在自我规范上不好,
   即使编译器没有做强制限制,我们自己也要限制自己。
// 不然,延展方法就毫无意义可言。 


          注:还可通过界面创建延展 


 


二.代码块Block


  1.block的基本概念 


Block对象是一个C级别的语法和运行机制。它与标准的C函数类似,

不同之处在于,它除了有可执行代码以外,它还包含了与堆、栈内

存绑定的变量。因此,Block对象包含着一组状态数据,这些数据在

程序执行时用于对行为产生影响。


你可以用Block来写一些可以传到API中的函数语句,可选择性地

存储,并可以使用多线程。作为一个回调,Block特别的有用,因

为block既包含了回调期间的代码,又包含了执行期间需要的数据。


由于Objective-C 和 C++ 都是衍生自 C,block被设计为可同时兼容这三种语言。 

  2.block的基本用法

           

           ^操作符来声明一个Block变量,并指明Block述句的开始。Block的主体部分

               包含在 {}内,像下面的例子中一样(与C语法一样,“;”指明语句的结束): 

   

  

1) block最简单形式

定义格式:


void (^block名)() = ^{代码块;} 


使用格式:

block名(); 

2) block带有参数的block的定义和使用格式:

void (^block名称)(参数列表)

= ^ (参数列表) { // 代码实现; } 


3) 带有参数和返回值的block格式:


返回类型 (^block名称)(参数列表)

= ^ 返回类型 (参数列表) { // 代码实现; } 


   3.block的typedef 


        利用typedef定义block类型(和指向函数的指针很像)


格式:

typedef 返回值类型 (^block变量名)(参数类型列表);

Typedef int(^MyBlock)(int ,int);


速记符:以后就可以利用这种类型来定义block变量了。 


  4.block访问外部变量

1)在block内部可以访问block外部的变量


在block内部可以变量,但是注意,这是一个新的内存空间变量 


block内部也可以定义和block外部的同名的变量(局部变量),此时局部变量会暂时屏蔽外部变量的作用域 



2)在block内部不可以修改block外部的变量


默认情况下,Block内部不能修改外部的局部变量 


给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。 


  5.block作为函数的返回值


         步骤:

               1)使用typedef 定义一个新的类型 

               2)使用新类型作为函数的返回值 

               3)定义变量接收函数返回的值(block类型)

               4)调用block 



  6.block使用技巧及注意


1) block 结构的快速提示利用

2) block变量用作方法的参数的时候最好把参数类型列表部分加上具体的形参名 





三.protocol代理设计模式

  1.protocol概念及基本使用 


(1)protocol的基本概念 

在写java的时候都会有接口interface这个概念,接口就是一堆方法

的声明没有实现,而在OC 里面,Interface是一个类的头文件的声明,

并不是真正意义上的接口的意思,在OC中,接口是由 一个叫做协议

的protocol来实现的。 


这个里面可以声明一些方法,和java不同的是,它可以声明一些必须

实现的方法和选择实现 的方法。这个和java是完全不同的。 


(2)protocol的使用流程 

协议的使用流程: 

定义协议----> 在类中采用指定的协议 ---->实现协议中的方法

(注意方法有必须实现和选择实现两种)

1)定义协议 

协议的定义 

@protocol 协议名称 <NSObject> //默认遵NSObject协议 

//方法声明列表 

@end; 

注意: 协议默认的要采纳NSObject的协议 

 

2)采纳协议 

类遵守协议 

   创建类的时候遵守某个或者某几个协议

@interface 类名 : 父类 <协议名称> @end 

//默认遵守NSObject协议 

@interface 类名 : 父类 <协议名称1,协议名称2> @end 

某个协议也遵守某个或者某些协议,一个协议可以遵守其他多个协议 

1>协议遵守协议 

@protocol 协议名称 <其他协议名称> 

@end 

2>多个协议之间用逗号 , 隔开。 

@protocol 协议名称 <其他协议名称1, 其他协议名称2> @end 

3)实现协议中的方法 



  2.protocol的基本使用 


1)定义协议 

协议的定义 
@protocol 协议名称 <NSObject> 
//方法声明列表 
@end; 

注意: 协议默认的要采纳NSObject的协议

2)采纳协议 

注意:采纳协议要先把要采纳的协议引入过来 

1>类遵守协议 : 某个类遵守某个协议 

2>协议遵守协议 

@protocol 协议名称 <其他协议名称> @end; 

3)实现协议中的方法 

如果一个类遵守了某个协议 则只需要在这个类的实现(.m)文件中,实现协议的方法就可以了 

注:也使用图形界面创建协议

  3.OC中的协议(protocol)使用注意: 

1)Protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现。 

2)只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。 

3)只要父类遵守了某个协议,那么子类也遵守。 

4)Protocol声明的方法可以让任何类去实现,protocol就是协议。 

5)OC不能继承多个类(单继承)但是能够遵守多个协议。继承(:),遵守协议(< >) 

6)基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。 

7)协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明 

注: 1)协议之间可以有继承关系 

    2)类如果采纳协议后,实现了协议的方法,这些方法可以被子类继承 

 

  4.protocol基协议介绍 

NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它,它

还有名字也叫 NSObject的协议,它是一个基协议,最根本最基本的协议 

NSObject协议中声明很多最基本的方法 description 

     retain

     release

建议每个新的协议都要遵守NSObject协议

 

  5.protocol中@required和@optional 

@required和@optional是协议方法声明中的两个关键字他们主要用于控制方法

是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流 

@public

@protected

@private

@package

@required:这个方法必须要实现(若不实现,编译器会发出警告) 

@optional这个方法不一定要实现 


  6. protocol类型限制 

1)使用id存储对象时,对象的类型限制 

格式:id <协议名称> 变量名 

2)对象赋值时类型限制 使用类也同样如此 

格式:类名<协议名称> *变量名 

3)对象关联关系下,对象的类型限制


  7.id和instancetype的区别 

id和instancetype的区别: 

1)instancetype只能作为函数或者方法的返回值 

2)id能作为方法或者函数的返回值、参数类型,也能用来定义变量 

3)instancetype对比id的好处 

  * 能精确地限制返回值的具体类型 


  8.protocol代理设计模式引入 


代理模式是在oc中经常遇到的一种设计模式,那什么叫做代理模式呢? 

举个例子:有一个婴儿,他本身不会自己吃饭和洗澡等等一些事情,于

是婴儿就请了一个保姆,于是婴儿和保姆之间商定了一个协议,协议

中写明了保姆需要做什么事情, 而保姆就是这个代理人, 即:婴儿和

保姆之间有个协议,保姆遵守该协议,于是保姆就需要实现该协议中

的条款成为代理人。

 


  9. protocol代理设计模式概念 


代理模式概念


传入的对象,代替当前类完成了某个功能,称为代理模式


利用协议实现代理模式的主要思路为:


1)定义一个协议,里面声明代理类需要实现的方法列表

  比如这里一个代理类需要实现feedBabyHongSleep方法

2)创建一个代理类(比如BaoMu),遵守上面的代理协议 
3)在需要代理的类中(Baby),定义一个对象类型为id且遵守代理协议的成员变量 
4)Baby类中调用成员变量_delegate(代理)的方法,调用代理类的方法 
5)main.m或其他使用Baby类的文件中,Baby类的成员变量(代理类)赋值 



  10.protocol代理模式应用场合 


代理设计模式的场合:
* 当对象A发生了一些行为,想告知对象B 

(让对象B成为对象A的代理对象)
* 对象B想监听对象A的一些行

为(让对象B成为对象A的代理对象)
* 当对象A无法处理某些行为

的时候,想让对象B帮忙处理 (让对象B成为对象A的代理对象) 

1)监听器的场合
* Teacher想监听Baby的一些行为 
2)通知的场合
* Baby发生了一些行为,想告知Teacher 

3)有些事情,不想自己处理,想交给别人处理
* Baby发生了一些

  行为, 但是自己不会处理可以交给Teacher处理 


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fighting__bj/article/details/46757459

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签