设为首页 加入收藏

TOP

IOS开发系列--Objective-C之协议、代码块、分类(一)
2017-10-13 10:33:37 】 浏览:7527
Tags:IOS 开发 系列 --Objective-C 协议 代码 分类

协议protocol

在ObjC中使用@protocol定义一组方法规范,实现此协议的类必须实现对应的方法。熟悉面向对象的童鞋都知道接口本身是对象行为描述的协议规范。也就是说在ObjC中@protocol和其他语言的接口定义是类似的,只是在ObjC中interface关键字已经用于定义类了,因此它不会再像C#、Java中使用interface定义接口了。更多技术分享请关注微信appyykf

假设我们定义了一个动物的协议AnimalDelegate,人员Person这个类需要实现这个协议,请看下面的代码:

AnimalDelegate.h

// // AnimalDelegate.h // Protocol&Block&Category //定义一个协议 @protocol AnimalDelegate @required //必须实现的方法 -(void)eat; @optional //可选实现的方法 -(void)run; -(void)say; -(void)sleep; @end 

 

Person.h

// // Person.h // Protocol&Block&Category // #import  #import "AnimalDelegate.h" @interface Person : NSObject -(void)eat; @end 

Person.m

// // Person.m // Protocol&Block&Category // #import "Person.h" @implementation Person -(void)eat{ NSLog(@"eating..."); } @end 

这里需要说明几点:

  1. 一个协议可以扩展自另一个协议,例如上面AnimalDelegate就扩展自NSObject,如果需要扩展多个协议中间使用逗号分隔;
  2. 和其他高级语言中接口不同的是协议中定义的方法不一定是必须实现的,我们可以通过关键字进行@required和@optional进行设置,如果不设置则默认是@required(注意ObjC是弱语法,即使不实现必选方法编译运行也不会报错);
  3. 协议通过<>进行实现,一个类可以同时实现多个协议,中间通过逗号分隔;
  4. 协议的实现只能在类的声明上,不能放到类的实现上(也就是说必须写成@interface Person:NSObject而不能写成@implementation Person);
  5. 协议中不能定义属性、成员变量等,只能定义方法;

事实上在ObjC中协议的更多作用是用于约束一个类必须实现某些方法,而从面向对象的角度而言这个类跟接口并不一定存在某种自然关系,可能是两个完全不同意义上的事物,这种模式我们称之为代理模式(Delegation)。在Cocoa框架中大量采用这种模式实现数据和UI的分离,而且基本上所有的协议都是以Delegate结尾。

现在假设需要设计一个按钮,我们知道按钮都是需要点击的,在其他语言中通常会引入事件机制,只要使用者订阅了点击事件,那么点击的时候就会触发执行这个事件(这是对象之间解耦的一种方式:代码注入)。但是在ObjC中没有事件的定义,而是使用代理来处理这个问题。首先在按钮中定义按钮的代理,同时使用协议约束这个代理(事件的触发者)必须实现协议中的某些方法,当按钮处理过程中查看代理是否实现了这个方法,如果实现了则调用这个方法。

KCButton.h

// // KCButton.h // Protocol&Block&Category // #import  @class KCButton; //一个协议可以扩展另一个协议,例如KCButtonDelegate扩展了NSObject协议 @protocol KCButtonDelegate @required //@required修饰的方法必须实现 -(void)onClick:(KCButton *)button; @optional //@optional修饰的方法是可选实现的 -(void)onMouseover:(KCButton *)button; -(void)onMouseout:(KCButton *)button; @end @interface KCButton : NSObject #pragma mark - 属性 #pragma mark 代理属性,同时约定作为代理的对象必须实现KCButtonDelegate协议 @property (nonatomic,retain) id delegate; #pragma mark - 公共方法 #pragma mark 点击方法 -(void)click; @end 

KCButton.m

// // KCButton.m // Protocol&Block&Category #import "KCButton.h" @implementation KCButton -(void)click{ NSLog(@"Invoke KCButton's click method."); //判断_delegate实例是否实现了onClick:方法(注意方法名是"onClick:",后面有个:) //避免未实现ButtonDelegate的类也作为KCButton的监听 if([_delegate respondsToSelector:@selector(onClick:)]){ [_delegate onClick:self]; } } @end 

MyListener.h

// // MyListener.h // Protocol&Block&Category  
#import  @class KCButton; @protocol KCButtonDelegate; @interface MyListener : NSObject -(void)onClick:(KCButton *)button; @end 

MyListener.m

// // MyListener.m // Protocol&Block&Category #import "MyListener.h" #import "KCButton.h" @implementation MyListener -(void)onClick:(KCButton *)button{ NSLog(@"Invoke MyListener's onClick method.The button is:%@.",button); } @end 

main.m

// // main.m // Protocol&Block&Category #import  #import "KCButton.h" #import "MyListener.h" int main(int argc, const char * argv[]) { @autoreleasepool { KCButton *button=[[KCButton alloc]init]; MyListener *listener=[[MyListener alloc]init
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【Swift学习】Swift编程之旅---析.. 下一篇iOS的APP验证版本更新方法

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目