【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 ...
随机推荐
- pyqt样式表语法笔记(下)--原创
pyqt样式表语法笔记(下) python 启动界面 QSS pyqt 一.启动界面的设置 简单点~说话的方式简单点用一张静态图片作为程序启动界面为例. 原来的语句 python 7行 ...
- Java EE基础之JSP(二)
接着上篇文章,我们上篇文章讲到了jsp的基本原理以及和servlet的关系,还介绍了jsp的基本语法部分,本篇文章就继续介绍余下的内容. 编译指令Page和include 基本的动作指令 内置对象 一 ...
- Sublime Text 3下载-汉化-插件配置
Sublime Text 3下载 不用说是上官方下载地址:http://www.sublimetext.com/3 Sublime Text 3 免费使用方法 Sublime Text 2的时候还有一 ...
- java.lang.NoClassDefFoundError异常
1.错误信息 2.错误分析: JVM读到程序的第三行,会在当前路径 "D:\java" 下寻找com.yangquan.aolun这个包路径下的Cat类,但当前路径下根本就没有co ...
- 数据库DDL操作
DDL1. 数据库* 查看所有数据库:SHOW DATABASES* 切换(选择要操作的)数据库:USE 数据库名* 创建数据库:CREATE DATABASE [IF NOT EXISTS] myd ...
- vuejs单一事件管理组件间的通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 参加光环国际PRINCE2培训
挑战埃及是全球首套能够同时适配PRINCE2认证人群,PMP认证人群的项目管理沙盘演练游戏.沙盘通过使用乐高积木作为道具,通过一场互动性极强的情景模拟为全球项目经理还原了四千年前古埃及金字塔建造的情景 ...
- Java基础—String类小结
一.String类是什么 public final class String implements java.io.Serializable, Comparable<String>, Ch ...
- 老李分享:Android -自动化埋点 2
除了上述的事件,Android提供了一个OnTouchListener的监听器,当事件传递到控件的时候,如果控件注册了这个监听器,则会执行监听器中的onTouch方法.同时,如果它返回true,则事件 ...
- 奇葩问题:同样的字符串equal为false
问题:什么情况下 "同样" 的字符串会不equal呢?例如 "a".equal("a") => false 在你看来,这可能是个 ...