华山论剑之浅谈iOS的 target - action设计模式 和 代理模式 以及Bolck

当我们觉得一件事情是理所当然的时候,那正是我们失去它的时候.

target - action设计模式 和 代理模式 以及Bolck 不管是哪一个,都是我们在编程过程中比较常用的,但是真正有多少人还记得他们的实现原理的?今天我就浅谈一下target - action设计模式 和 代理模式 以及Bolck 这三个模块.在谈之前,我们先看一张搞笑的图片,让我们对三种模式有个初步的了解.

设计模式


target - action设计模式


target - action设计模式 是一种比较常见的设计模式,比如我们在用button的时候,给button添加一个事件,我们就用到了target - action设计模式.现在我们就用target - action设计模式 做一个button,还原button的设计原理,当然了 我们还要加上tap手势.

现在我们在我们的.tapView.h中做两个属性 一个target属性,另外一个是action属性,然后声明一个target - action方法.

#import <UIKit/UIKit.h>

@interface TapView : UIView
//目标
@property(weak,nonatomic)id target;
//行为
@property(assign,nonatomic)SEL action;

//自定义方法
-(void)addCustomtarget:(id)target andAction:(SEL)action;

@end

在tapView.m文件中我们要两个方法进行实现,一个是-(void)addCustomtarget:(id)target andAction:(SEL)action;另外一个就是-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;这个方法就是模拟button功能的方法.原理就是如果有一个执行者和一个执行者能做的方法,那么我们就让执行者执行那个方法.

#import "TapView.h"

@implementation TapView

//自定义方法
-(void)addCustomtarget:(id)target andAction:(SEL)action{

    _action = action;
    _target = target;
    
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    //当视图点击的时候,target去执行action的方法并把自己传过去.
    //首先代理不能是空,而且代理(代理是对象!)的类中有方法并且能传出过来.
    if (nil != _target && [[_target class] instancesRespondToSelector:_action]) {
        [_target performSelector:_action withObject:self];
     
    }
    
}


代理模式


代理模式是什么?代理模式就是制定一个执行者去做某件事情,是不是觉得跟target - action设计模式很相似?我们现在就对代理模式进行一下代码的尝试.

在.h文件中我们首先要声明一个协议,然后在协议中声明我们要实现的代理方法,然后我们要在这个类的声明一个代理的属性,这里我就做一个当我们点击我们的视图的时候就会改变的颜色.

#import <UIKit/UIKit.h>

@protocol TouchViewDelegate <NSObject>

-(void)changeViewColor:(UIColor *)color;

@end


@interface TouchView : UIView

//声明一个代理,这个代理遵守TouchViewDelegate协议,
@property(nonatomic,assign)id<TouchViewDelegate> delegate;

@end

在.m中,我们要对代理的方法进行调用一下,这里我传的是一个颜色.

#import "TouchView.h"

@implementation TouchView

//我们还是用touchesBegandian
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    if (nil != self.delegate && [self.delegate respondsToSelector:@selector(changeViewColor:)]) {
        
        //我们传一个颜色到我们的ViewController去.
        [self.delegate changeViewColor:[UIColor brownColor]];
        
    }
    
}

@end

然后我们看一下在ViewController.m中所要做的操作吧.还记得nil != self.delegate && [self.delegate respondsToSelector:@selector(changeViewColor:)]这句代码吗?意思还是当我们的代理人存在,并且他有代理方法,那么我们就让代理人实现代理方法.


#import "ViewController.h"

#import "TouchView.h"

//在这里ViewController 要遵守协议....
@interface ViewController ()<TouchViewDelegate>

@property(nonatomic,strong)TouchView *touchView;

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    self.touchView = [[TouchView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    
    self.touchView.backgroundColor = [UIColor redColor];
    //指定touchView的代理为ViewController.即为本身~
    self.touchView.delegate =self;
    
    [self.view addSubview: self.touchView];
}

-(void)changeViewColor:(UIColor *)color{

    //现在参数color是有值的,这是因为在TouchView那个页面传过来的.
    self.touchView.backgroundColor = color;


}



@end



Bolck


Bolck块在我们的编程过程中也是很常用的,它叫匿名函数,其实它不是函数,而是一个数据类型,就如同int,char一样,但是要给Bolck赋的值却是一个函数!!Bolck保存的是一个函数..当我们不懂的时候,是可以这样的理解的..当然,我们使用Bolck和代理模式很多时候是用于做传值使用的.

现在我们做一个OtherViewController 和ViewController两个控制器界面之间的传值,我们就使用Bolck来完成这件事情 ,首先我们在OtherViewController.h 声明一个Bolck的属性,当然了,我们需要先改一下名字,让我们的Bolck不是那么的难看.

#import <UIKit/UIKit.h>

//给block改名成MyBlock
typedef void(^MyBlock)(NSString *);


@interface OtherViewController : UIViewController

//MRC:block的语义设置是copy,把block从栈区拷贝到堆区.使用完之后,在dealloc内释放
//ARC:语义设置使用strong即可
@property(nonatomic,strong)MyBlock block;

@end

现在在我们的.m中进行如下的操作,我们有个输入框textField,当我们输入完成之后,我们点击一下页面返回到ViewController 然后把值传给ViewController.

#import "OtherViewController.h"

@interface OtherViewController ()

@property(nonatomic,strong)UITextField *textField;

@end

@implementation OtherViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 100, 414, 40)];
    
    self.textField.backgroundColor = [UIColor lightGrayColor];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    [self.view addSubview: self.textField];
    
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{


    self.block(_textField.text);

    
    [self.navigationController popViewControllerAnimated:YES];

}
@end


我们在ViewController中做了哪些操作呢?如下,我们需要声明一个OtherViewController的属性,然后给OtherViewController对象的block进行赋值.然后就是push页面了~


#import "ViewController.h"


#import "OtherViewController.h"

@interface ViewController ()

@property(nonatomic,strong)OtherViewController *otherVC;

@property(nonatomic,strong)UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.label = [[UILabel alloc]initWithFrame:CGRectMake(0, 100, 414, 40)];
    
    self.label.backgroundColor = [UIColor lightGrayColor];
    
    [self.view addSubview:self.label];
    
    
    
    
}


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    
    self.otherVC = [[OtherViewController alloc]init];
    
    __weak typeof(self)weak = self;
    
    //给block赋值~
    self.otherVC.block = ^(NSString *string){
        
        weak.label.text = string;
        
    };
    
    
    [self.navigationController pushViewController:_otherVC animated:YES];
    

}



@end

现在我们用图说明一下block传值的实现原理.

block设计模式


target - action设计模式 和 代理模式 以及Bolck在编程过程中用的比较多,这里就做一下简单的介绍.希望大家能够喜欢这篇文章.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容