大发快三_快三回血_大发快三回血

【原】谈谈对Objective

时间:2020-01-08 07:53:12 出处:大发快三_快三回血_大发快三回血

本文转载请注明出处 —— polobymulberry-博客园

1. 前言


这篇文章主已经 对代理模式和委托模式进行了对比,买车人认为Objective-C中的delegate大部分用法属于委托模式。全文或多或少抠概念,对实际开发非要 任何影响。

前段时间想看 的一篇博客iOS开发——从一道题看Delegate,和这篇博客iOS APP 架构漫谈补救的问提相似。两篇blog都写得很不错,全部都是为了补救一个多多多多 页面之间的数据传递问提:

A页面中一个多多多多多 UILabel *labelA,B页面中一个多多多多多 UITextField *textFieldB。从A页面跳转到B页面后,更改textFieldB中数据再返回到A页面,labelA显示的将是textFieldB中更改后的数据,嗯,已经 非要 简单的一个多多多多 数据传递场景。

补救或多或少问提依据已经 ,比如使用一个多多多多 DAO(data access object)去维护labelA和textFieldB所对应的数据。页面的数据流向如下图已经 :

刚刚 或多或少场景全部都是很僵化 ,已经 不用 时要引入DAO非要 重的架构。

有刚刚或多或少人会陷入技术的细节不可自拔,不妨静下来想一想,或多或少问提本质在哪几种?

或多或少问提的难点在于页面B中textFieldB的数据变化后无法通知页面A中的labelA。肯能页面B含有labelA的引用就好了,已经 就还不用 直接在页面B的代码中操作labelA。于是我在页面B中加进去去了一个多多多多 UILabel *labelARef,在A页面push到B页面时,将页面A的labelA赋值给labelRef即可(亲测还不用 进行数据传递)。

上述依据嘴笨 可行,不过或多或少人肯定都嘴笨 已经 设计也是很深暴了。肯能数据传递的业务比较多,非要 页面B中就时要引用已经 页面A的属性。当然或多或少人还不用 直接引用页面A作为页面B的属性,即UIViewController *vcA。如下图所示:

已经 设计嘴笨 没啥问提。不过或多或少人这次主题是代理模式,已经 们说的或多或少问提到底和代理模式有哪几种联系呢?

2.使用代理模式实现数据传递


或多或少人先看看GoF《设计模式:可复用面向软件的基础》中对代理模式的描述:为或多或少对象提供这人代理以控制对或多或少对象的访问。咦,是全部都是和上边或多或少问提很像?为页面B提供这人代理以控制页面A的访问,能控制页面A,那就能控制页面A中的labelA。已经 上边那种直接引用对象的依据也还不用 提供对或多或少对象的访问啊,为哪几种一定要通过代理呢?或多或少人来看下代理模式的UML图:

注意上图中Proxy和RealSubject都实现了Subject或多或少接口,刚刚 实现了相同的接口函数DoAction(),另外Proxy存有一份RealSubject的引用,即图中的delegate。一般来说,Proxy在实现DoAction时,会调用RealSubject的DoAction,也已经 利用所引用的delegate调用RealSubject的DoAction。按照我买车人的理解,并非 会出先代理模式,是肯能用户时要对RealSubject的DoAction功能进行扩展,又无法对RealSubject中的DoAction直接进行修改(刚刚 也违反了封闭-开放原则),于是使用了Proxy对RealSubject的DoAction进行了扩展,而扩展的内容全部都是DoAction,已经 又将DoAction抽象出来,做成了接口。

回到上边那个案例,或多或少人还不用 利用代理模式进行如下分派:

这里介绍一个多多多多 小技巧,即如何辨别谁是代理 —— 直接跟Client打交道的是代理,此处Client已经 ViewControllerB的textFieldB控件,已经 直接打交道的已经 ViewControllerB,也已经 说ViewControllerB是代理。

代码如下:

// DataTransDelegate

// DataTransDelegate
@protocol DataTransDelegate <NSObject>
- (void)didTextFieldChanged:(UITextField *)textField;
@end

// ViewControllerA

// ViewControllerA.m
#import "ViewControllerA.h"
#import "ViewControllerB.h"
#import "DataTransDelegate.h"

@interface ViewControllerA () <DataTransDelegate>
@property (strong, nonatomic) UILabel *labelA;
@property (strong, nonatomic) UIButton *buttonA;
@end

@implementation ViewControllerA

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.view addSubview:self.labelA];
    [self.view addSubview:self.buttonA];
    
    [self.buttonA addTarget:self action:@selector(pushVC) forControlEvents:UIControlEventTouchUpInside];
}

- (void)pushVC
{
    ViewControllerB *vcB = [[ViewControllerB alloc] init];
    vcB.delegate = self;
    [self.navigationController pushViewController:vcB animated:NO];
}

- (void)didTextFieldChanged:(UITextField *)textField
{
    self.labelA.text = textField.text;
}

- (UILabel *)labelA
{
    if (_labelA == nil) {
        _labelA = [[UILabel alloc] initWithFrame:CGRectMake(400, 400, 400, 400)];
        _labelA.text = @"显示vcB中的textField内容";
    }
    return _labelA;
}

- (UIButton *)buttonA
{
    if (_buttonA == nil) {
        _buttonA = [[UIButton alloc] initWithFrame:CGRectMake(400, 400, 400, 400)];
        _buttonA.backgroundColor = [UIColor blueColor];
        [_buttonA setTitle:@"进入vcB" forState:UIControlStateNormal];
    }
    return _buttonA;
}

@end

// ViewControllerB

// ViewControllerB.h
@protocol DataTransDelegate;

@interface ViewControllerB : UIViewController
@property (nonatomic, weak) id<DataTransDelegate> delegate;
@end

// ViewController.m
#import "ViewControllerB.h"
#import "DataTransDelegate.h"

@interface ViewControllerB () <UITextFieldDelegate, DataTransDelegate>
@property (strong, nonatomic) UITextField *textFieldB;
@end

@implementation ViewControllerB

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.view addSubview:self.textFieldB];
    self.textFieldB.delegate = self;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self didTextFieldChanged:textField];
}

- (void)didTextFieldChanged:(UITextField *)textField
{
    [self.delegate didTextFieldChanged:textField];
}

- (UITextField *)textFieldB
{
    if (_textFieldB == nil) {
        _textFieldB = [[UITextField alloc] initWithFrame:CGRectMake(400, 400, 400, 400)];
        _textFieldB.text = @"输入文字";
        _textFieldB.backgroundColor = [UIColor redColor];
    }
    return _textFieldB;
}

@end

效果如下:

3.关于代理模式误解


嘴笨 到目前为止并非要 哪几种异样。关键是在或多或少人对Objective-C的protocol使用上,一般是结合delegate使用的。大多数或多或少人称或多或少模式是代理模式,刚刚 我嘴笨 delegate更像是这人委托模式,而非真正意义上的代理,代理是proxy,而委托是delegate。另外,代理模式中代理和被代理者都时要继承并实现同一个多多多多 接口Subject,而或多或少人使用delegate一般只时要让其中一个多多多多 类继承并实现对应接口即可。

委托模式是软件设计模式中的一项基本技巧。在委托模式中,一个多多多多多 对象参与补救同一个多多多多 请求,接受请求的对象将请求委托给已经 对象来补救。嘴笨 上边的viewControllerB含有了viewControllerA的引用或多或少做法已经 委托模式。

比如或多或少人最为熟知的UITableView,已经 一个多多多多 典型的委托模式,它将tableView的中不变的部分封装起来,将无缘无故变化的部分委托给用户买车人补救,已经 说UITableView已经 一个多多多多 delegator,而遵循UITableViewDelegate的那个类已经 delegate,已经 或多或少人无缘无故会在一个多多多多 UIViewController中使用相似self.tableView.delegate = self已经 的表达;

或多或少人肯能会疑惑为哪几种还时要使用UITableViewDelegate或多或少相似于Java中的interface?我买车人理解是肯能已经 方便统一接口,接口统一了,方便了用户,肯能只时要实现这有几条接口就还不用 了。

已经 或多或少人还不用 想看 最现在开始提到的两篇博客嘴笨 借助了Objective-C中的protocol实现了的嘴笨 是委托模式。

肯能非要说委托模式和代理模式哪几种关系说说,我嘴笨 代理模式应该算不算这人特殊的委托模式。

热门

热门标签