1

我对 iOS 开发有点陌生,来自 Java / Android 背景。我的理解是,您的习惯ProtocolsDelegates就像Interfaces在 Java 土地上一样。

如果是这样,那么我相信这些Protocols也是Objects如此。

案子:

  • 假设 2ViewController秒,Home并且Profile
  • 1 Presenter,我们称它在两个sStuffPresenter中单独实例化。ViewController
  • StuffPresenter有一个被调用的初始化方法initWithInteractor,它接受一个参数,Interactor该参数是一个协议。
  • Home 和 Profile 都实现了一个Protocol名为 Interactor,它有一个名为 的方法initStuffInTableView(NSMutableArray *)stuff

所以我有一个两难的境地,如果我在其中Home传递StuffPresenter信息然后我切换到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。为什么会这样?

4

2 回答 2

1

Aprotocol是一种 Objective-C 语言特性,用于指定一个类(或另一个协议)具有某些特性,以使编译器/ARC/程序员受益。

Adelegate或委托,是一种使模型视图控制器更容易的设计模式。为了让做委托的对象更加灵活,一般它的委托都采用协议。

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

  1. 您的 Presenter 与其交互者有一个参考循环
  2. 您需要调用一些init最终调用[super init]Presenter 方法的initWithInteractor:方法。
  3. 正如其他人指出的那样,您的方法以init违反 Objective-C 约定开始。

很难从您发布的内容中确切地说出您的问题是什么,但我非常怀疑它的结构。

你有一个类(Presenter),你创建了两个实例,并且除了交互器之外不传递任何参数。

每个实例如何知道根据它作为参数接收到的视图控制器来加载不同的“东西”?

于 2015-09-07T00:27:25.033 回答
0

我仍然想彻底了解这里发生了什么,但我确实通过执行以下操作解决了问题。

HomeProfile中,我在这里初始化StuffPresenter

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

退出控制器视图时,我执行以下操作:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    _stuffPresenter = nil;
}
于 2015-09-06T21:01:46.760 回答