【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 ...
随机推荐
- iOS全角符与半角符之间的转换
iOS全角符与半角符之间的转换 相关资料: 函数『CFStringTransform』中文 详情: 问题 1.17-03-15,「有人在群里边问怎么把『半角』符字符串转换成『全角』字符串?」,百度的 ...
- JavaScript复习之--javascript数据类型隐式转换
JavaScript数据类型隐式转换.一,函数类 isNaN() 该函数会对参数进行隐式的Number()转换,如果转换不成功则返回true. alert() 输出的内容隐式的 ...
- php写留言板
简单的PHP留言板制作 做基础的留言板功能 需要三张表: 员工表,留言表,好友表 首先造一个登入页面: <form action="drcl.php" method=&qu ...
- 使用 ipdb 调试 Python
1.安装 pip install ipdb 2.使用 python -m ipdb xxx.py 程序内部: from ipdb import set_trace set_trace() 3.常用命令 ...
- WebApi client 的面向切面编程
.Net的面向切面编程 .Net的服务端应用AOP很常见,在Asp.net MVC与Asp.net WebApi等新框架里到处都有AOP的影子,我们可以把一个服务方法“切”为很多面,日志面.验证面.请 ...
- RabbitMQ集群搭建
准备三个节点,系统为CentOS7 Node IP rabbitmq01 172.50.0.64 rabbitmq02 172.50.0.65 rabbitmq03 172.50.0.66 这里把no ...
- 疯狂的 JAVA 后++
一.x++ 所以执行完x++之后,局部变量区的x值,直接为2: iinc: 指定int型变量增加指定的值,注意是变量,我的解释是iinc直接对局部变量操作,而不是对操作栈进行操作! ★★★★ OUTP ...
- Snapman设计中的思考
Snapman主页:http://www.snapman.xyz 原文链接地址:http://www.snapman.xyz/newsitem/277785310 feiren工作室主要研究人类 ...
- Crgwin 简介及安装
Crgwin 简介 Cygwin是一个在windows平台上运行的类UNIX模拟环境,是cygnus solutions公司开发的自由软件(该公司开发的著名工具还有eCos,不过现已被Redhat收购 ...
- 修改Gradle 和Maven本地仓库的位置 方法
关于Maven的配置: 用过Maven的兄弟应该知道Maven可以通过配置 conf文件夹下面的settings.xml文件来修改maven下载的包,默认是下在c盘的用户文件夹下的.m2中,日积月累. ...