【问题标题】:Protocol being called in two different classes at same time同时在两个不同的类中调用协议
【发布时间】:2015-12-02 08:01:26
【问题描述】:

我对 iOS 开发有点陌生,来自 Java / Android 背景。我的理解是,您自定义的ProtocolsDelegates 就像Java 领域中的Interfaces

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

案例:

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

所以我有一个两难境地,如果我在 HomeStuffPresenter 中继信息,然后我切换到 ProfileStuffPresenterHomeProfile 中加载内容。

为什么会这样?

这是我设置的代码:

协议

@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 时,应用程序崩溃了,因为在 Home 中调用了 initStuffInTableView。为什么会这样?

【问题讨论】:

  • 次要点:如果方法是调用[super init..] 的初始化程序,则它们只能以单词init 开头。并且只能在初始分配/实例化期间调用它们。
  • 谢谢你的意思,我习惯于在Java 中设置不同的构造函数,我如何在Objective C 土地上最好地完成它?我的理解是我可以设置自定义 initWith&lt;key-word&gt; 方法。
  • 你仍然可以有不同的构造函数,我只是说你不应该将init 用于不是构造函数/初始化器的方法:) 见herehere
  • 啊,好吧,您指的是我的自定义初始化方法,例如 initPresenterinitPullToRefresh 是的,这很有意义。
  • 我认为我将这些方法命名为 setup&lt;key-word&gt; 继续前进。

标签: ios objective-c protocols presenter


【解决方案1】:

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

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

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

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

很难从您发布的内容中准确判断您的问题是什么,但我非常怀疑它的结构。

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

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

【讨论】:

  • 如果您熟悉我在上面部署的模型视图演示者模式,当然这些不是演示者中唯一的方法。假设我们有一个名为Stuff 的实体,然后StuffPresenter 将处理与Stuff 相关的任何数据的呈现和发送。我的想法是让视图控制器只与控制和呈现视图相关。从而防止大量视图控制器。
  • 既然您对我的代码有批评,请发布更多关于如何修复它的具体示例?例如,请提供第 2 点的更详尽示例。)。还要更详细地解释第 1 点。
【解决方案2】:

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

HomeProfile 中,我在这里初始化StuffPresenter

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 2013-11-14
    相关资源
    最近更新 更多