【原】谈谈对Objective

  • 时间:
  • 浏览:0
  • 来源:极速快3_快3软件_极速快3软件

本文转载请注明出处 —— 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实现了的着实 是委托模式。

机会不能了说委托模式和代理模式哪些关系语录,我着实 代理模式应该算是三种特殊的委托模式。