【Objective-C 基础】4.分类和协议
OC提供了一种与众不同的方式--Category,可以动态的为已经存在的类添加新的行为(方法)
这样可以保证类的原始设计规模较小,功能增加时再逐步扩展。
使用Category对类进行扩展时,不需要创建子类
Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中
()代表着一个分类 ()中的代表者分类的名称
也可以为系统子类的类添加一些扩展方法
1.简单来说就是一系列方法的列表,其中声明的方法可以被任何类实现。这种模式一般称之为代理(delegation)模式。
2.模拟实现Button的点击监听机制
a.声明代理
#import <Foundation/Foundation.h>
@class Button;
//<>代表实现某个协议
@protocol ButtonDelegate <NSObject>
-(void)onClick:(Button *)btn;
@end @interface Button : NSObject
@property (nonatomic,retain) id<ButtonDelegate> delegate;
-(void)click;
@end
#import "Button.h"
@implementation Button
-(void)dealloc{
//释放Button 同时释放delegate
[_delegate release];
[super dealloc];
}
-(void)click{
//判断监听器是否有OnClick:方法
if([_delegate respondsToSelector:@selector(onClick:)]){
[_delegate onClick:self];
}else{
NSLog(@"监听器没有实现onClick方法");
}
}
@end
b.定义一个类ButtonListener遵循ButtonDelegate协议
#import <Foundation/Foundation.h> //对协议进行提前声明 ,跟@class的用途是一样的
@protocol ButtonDelegate; @interface ButtonListener : NSObject <ButtonDelegate> @end
#import "ButtonListener.h"
#import "Button.h"
@implementation ButtonListener -(void)onClick:(Button *)btn{
NSLog(@"ButtonListener已经监听到按钮%@被点击",btn);
}
@end
c.调用
#import <Foundation/Foundation.h>
#import "Button.h"
#import "ButtonListener.h" int main(int argc, const char * argv[])
{ @autoreleasepool { Button *button=[[[Button alloc] init]autorelease];
Button *button2=[[[Button alloc] init]autorelease];
ButtonListener *listener=[[[ButtonListener alloc] init]autorelease];
button.delegate=listener;
button2.delegate=listener;
//按钮1被点击
[button click];
[button2 click];
}
return ;
}
打印结果:
2013-08-29 22:00:24.276 Protocol[6473:303] ButtonListener已经见听到按钮<Button: 0x1001098d0>被点击
2013-08-29 22:00:24.281 Protocol[6473:303] ButtonListener已经见听到按钮<Button: 0x10010b690>被点击
3.Protocol补充
#import <Foundation/Foundation.h> @protocol Study <NSObject>
//不加限制 默认是required
//@required 表示必须实现的方法
//虽然是必须实现,但编译器并不强求某个类必须实现
@required
-(void)test;
-(void)test1;
//@optional 表示可选(可实现、也可以不实现)
@optional
-(void)test2;
@end
#import <Foundation/Foundation.h>
#import "Study.h"
#import "Learn.h"
@protocol Study,Learn;
//遵循多个协议
@interface Student : NSObject <Study,Learn> @end
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[])
{ @autoreleasepool {
Student *stu=[[[Student alloc ]init]autorelease];
//
if([stu conformsToProtocol:@protocol(Study)]){
NSLog(@"Student遵守了Study这个协议");
}
}
return ;
}
2013-09-02 21:44:08.659 Protocol[3491:303] Student遵守了Study这个协议
1.Block封装了一段代码,可以在任何时候执行。
a.Block定义和调用
//Block定义
int (^Add) (int,int)=^(int a,int b){
return a+b;
};
//调用Block
int a=Add(,);
NSLog(@"a=%i",a);//打印结果a=11;
b.使用typedef定义
typedef int (^Add) (int,int);
int main(int argc, const char * argv[])
{ @autoreleasepool {
Add add=^(int a,int b){
return a+b;
};
NSLog(@"123+321=%i",add(,));//打印结果
}
return ;
}
c.Block可以访问外面定义的局部变量,但是不能修改。声明变量使用__block关键字可以进行修改。
int i=;
int j=;
__block int k=;
Add add=^(int a,int b){
NSLog(@"i=%i",i);
//j=111;//variable is not assignable
k=;
NSLog(@"k=%i",k);
return a+b;
};
d.使用block实现回调
#import <Foundation/Foundation.h>
@class Button;
//<>代表实现某个协议
typedef void (^ButtonBlock) (Button *); @interface Button : NSObject
@property (nonatomic,assign) ButtonBlock block;
-(void)click;
@end
#import "Button.h"
@implementation Button
-(void)click{
_block(self);
}
@end
#import <Foundation/Foundation.h>
#import "Button.h"
int main(int argc, const char * argv[])
{ @autoreleasepool {
Button *btn=[[[Button alloc] init]autorelease];
btn.block=^(Button *btn){
NSLog(@"按钮%@被点击了",btn);
};
[btn click];//打印:按钮<Button: 0x1001098d0>被点击了
}
return ;
}
2.Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似但是有区别。block是inline(内联函数)的,并且默认情况下它对局部变量是只读的。
3.苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多。
http://blog.csdn.net/totogo2010/article/details/7839061
【Objective-C 基础】4.分类和协议的更多相关文章
- iOS开发笔记系列-基础5(分类和协议)
分类 在Objective-C中,除了通过新建子类的方式来向类添加新方法外,还可以通过分类的方式.分类提供了一种简单的方式,将类的定义模块化到相关方法的组或分类中,它还提供了扩展现有类定义的简便方式, ...
- OC基础8:分类和协议
"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.关于分类(category): (1) ...
- 风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击
风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击 文件包含漏洞 参考文章:https://chybeta.github.io/2017/10/08/php文件包含漏洞/ 分类 ...
- OC基础:类的扩展.协议 分类: ios学习 OC 2015-06-22 19:22 34人阅读 评论(0) 收藏
//再设计一个类的时候,有些方法需要对外公开(接口),有些仅供内部使用. 类的扩展:为类添加新的特征(属性)或者方法 对已知类: 1.直接添加 2.继承(在其子类中添加实例变量和方法) 3.使用ext ...
- 网络基础知识-TCP/IP协议各层详解
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
- 04OC之分类Category,协议Protocol,Copy,代码块block
一.Protocol协议 我们都知道,在C#有个规范称之为接口,就是规范一系列的行为,事物.在C#中是使用Interface关键字来声明一个接口的,但是在OC中interface是用来声明类,所以用了 ...
- Objective-C语言分类与协议
分类(Category)允许向一个类文件中添加新的方法声明,它不需要使用子类机制,并且在类实现的文件中的同一个名字下定义这些方法.其语法举例如下: #import "ClassName.h& ...
- 网络编辑基础:对HTTP协议的头信息详解
HTTP(HyperTextTransferProtocol) 是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP 协议的详细内容请参 考RFC2616.HTTP协议采用了请求/响应模型 ...
- Objective-C /iphone开发基础:分类(category,又称类别)
在c++中我们可以多继承来实现代码复用和封装使程序更加简练.在objective-c中只能单继承,不能多继承,那么除了协议protocol之外,我们可以实现类似多继承的一个方法就是,分类(catego ...
随机推荐
- 提交任务到Spark
1.场景 在搭建好Hadoop+Spark环境后,现准备在此环境上提交简单的任务到Spark进行计算并输出结果.搭建过程:http://www.cnblogs.com/zengxiaoliang/p/ ...
- yum仓库,RPM打包
rpm命令: -qa 查看软件包是否被安装 -ivh 安装rpm包 -e 卸载包 -qpl 查看rpm包中有什么东西 -qi 查看软件的详细安装信息:安装路径 安装fpm #FPM是Ruby模块yu ...
- Intellij IDEA中文乱码解决
界面乱码 原因:IDEA默认设置界面的字体不支持中文 解决:修改为支持中文的字体,建议字体Microsoft Yahei UI.大小11,具体操作File -> Setting -> Ap ...
- linux最小安装
(1)系统安装类型选择及自定义额外包组 进入如图2-28所示界面.上半部分是系统定制的不同的系统安装类型选择项,默认是“Desktop”,这里我们选择“Minimal”,即最小化安装,下半部分是在上面 ...
- Shell常见用法小记
shell的简单使用 最近发现shell脚本在平常工作中简直算一把瑞士军刀,很多场景下用shell脚本能实现常用的简单需求,而之前都没怎么学习过shell,就趁机把shell相关的语法和常见用法总结了 ...
- MongoDB基础教程系列--第二篇 MongoDB基本操作(一)
1.安装环境 在官网上下载MongoDB的最新版本,根据自身Windows版本下载正确的MongoDB版本.下载后,双击32位或者64位.msi文件,按操作提示安装就可以了. 说明: 32 位版本的 ...
- 自动生成并导出word文档
今天很荣幸又破解一现实难题:自动生成并导出word文档 先看页面效果: word效果: 代码: 先搭建struts2项目 创建action,并在struts.xml完成注册 <?xml vers ...
- 老李案例分享:MAT分析应用程序服务出现内存溢出过程
老李案例分享:MAT分析应用程序服务出现内存溢出过程 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loa ...
- 优雅高效的MyBatis-Plus工具快速入门使用
目前正在维护的公司的一个项目是一个ssm架构的java项目,dao层的接口有大量数据库查询的方法,一个条件变化就要对应一个方法,再加上一些通用的curd方法,对应一张表的dao层方法有时候多达近20个 ...
- ReactJS入门3:组件的生命周期
本文主要介绍组件的生命周期. 组建的生命周期主要分为3个:Mounting.Updating.Unmounting. 1. Mounting:组件被加载到DOM 在本阶段,主要有三个方法: 1 ...