同时在两个不同的类中调用协议

时间:2015-09-06 19:09:05

标签: ios objective-c protocols presenter

我对iOS开发有点新兴,来自Java / Android背景。我的理解是,您的自定义ProtocolsDelegates与Java土地中的Interfaces类似。

如果是这种情况,那么我相信这些Protocols也是Objects

案例:

  • 假设2 ViewController s,HomeProfile
  • 1 Presenter,让我们称之为StuffPresenterViewController s中单独实例化。
  • StuffPresenter有一个名为initWithInteractor的初始化方法,它接受Interactor参数作为协议。
  • Home和Profile都实现了一个名为Interactor的Protocol,它有一个名为initStuffInTableView(NSMutableArray *)stuff的方法。

所以我陷入两难境地,如果我在HomeStuffPresenter中继信息,那么我会切换到ProfileStuffPresenter加载Home中的内容以及Profile

为什么会这样?

以下是我设置的代码:

协定

@protocol Interactor <NSObject>

- (void)initStuffInTableView:(NSMutableArray *)stuff;

@end

演示

@interface Presenter : NSobject

- (id)initWithInteractor:(id<Interactor>)interactor;
- (void)loadStuff;

@end

@implementation {
    @private
    id<Interactor> _interactor;
}

- (id)initWithInteractor:(id<Interactor>)interactor {
    _interactor = interactor;
    return self;
}

- (void)loadStuff {
    // Load stuff 
    NSMutableArray *stuff = // Init stuff in array...
    [_interactor initStuffInTableView:stuff];
}

@end

@interface HomeViewController : UITableViewController <Interactor>

- (void)initPresenter;

@end

@implementation {
    @private
    StuffPresenter *_stuffPresenter;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initPresenter];
    [self initPullToRefresh];
}

# pragma mark - init

- (void)initPresenter {
    _stuffPresenter = [[StuffPresenter alloc] initWithInteractor:self];
}

- (void)initPullToRefresh {
    // Init pull to refresh
    // ...
    [self.refreshControl addTarget:self
                            action:@selector(reloadStuff)
                  forControlEvents:UIControlEventValueChanged];
}

# pragma mark - Interactor

- (void)initStuffInTableView:(NSMutableArray *)stuff {
    // Do some work
    [self.tableView reloadData];
}

# pragma mark - reloadStuff

- (void)reloadStuff {
    [_stuffPresenter loadStuff];
}

# pragma mark - TableView methods here

// TableView methods...

@end

配置文件

@interface ProfileViewController : UITableViewController <Interactor>

- (void)initPresenter;

@end

@implementation {
    @private
    StuffPresenter *_stuffPresenter;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initPresenter];
}

# pragma mark - init

- (void)initPresenter {
    _stuffPresenter = [[StuffPresenter alloc] initWithInteractor:self];
    [_stuffPresenter loadStuff];
}

# pragma mark - Interactor

- (void)initStuffInTableView:(NSMutableArray *)stuff {
    // Do some work
    [self.tableView reloadData];
}

# pragma mark - TableView methods here

// TableView methods...

@end

问题:

当我转到Profile应用程序崩溃时,因为initStuffInTableView中正在调用Home。为什么会这样?

2 个答案:

答案 0 :(得分:1)

为了编译器/ ARC /程序员的利益,protocol是一种Objective-C语言功能,用于指定Class(或其他协议)具有某些功能。

delegate或委托是一种设计模式,它使模型视图控制器更容易。为了使进行委托的对象更加灵活,通常其委托采用协议。

您的代码中存在许多问题:

  1. 您的演示者与其互动者有一个参考周期
  2. 您需要调用一些最终在您的Presenter的init方法中调用[super init]的{​​{1}}方法。
  3. 正如其他人所指出的那样,以initWithInteractor:开头的方法违反了Objective-C约定。
  4. 很难说明您的问题确切地说明了您的问题是什么,但我非常怀疑其结构如何。

    您有一个类(Presenter),您可以创建两个实例,并且不传递交互器以外的任何参数。

    每个实例如何知道加载不同的东西&#34;基于它作为参数收到的View控制器?

答案 1 :(得分:0)

我仍然想彻底了解这里发生了什么,但我确实通过以下方式解决了这个问题。

HomeProfile中,我在这里初始化StuffPresenter

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animation];
    [self initPresenter];
}

退出controllerview时,我会执行以下操作:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    _stuffPresenter = nil;
}