3

我偶尔会通过传入视图控制器实例本身来从我的视图控制器实例化一个类,以便我创建的对象可以调用控制器的方法来更新视图。

这总是、经常或永远不是一个坏习惯吗?

具体来说:

ViewController.h 有

-(void)updateButtonValue:(NSString*)value;

MyObject.h 有

-(id)initWithViewController:(ViewController*)aViewController;

我从我的视图控制器实例化该类:

[[MyObject alloc] initWithViewController:self];

因此允许 MyObject 实例通过一个简单的调用来更新我视图中的按钮值,例如:

我的对象.m

[self.viewController updateButtonValue:@"example"];

这似乎并不理想,因为我传递给 MyObject 的内容(视图控制器本身)比它应该需要的多得多,但它肯定是快速且实用的。如果有更简洁的方法,例如依赖协议,也很简洁,一个简短的代码示例将不胜感激。

4

1 回答 1

4

传入类类型的指针总是不好的做法,因为您将对象紧密耦合在一起(每个对象都需要知道另一个对象的类,它们也可能是单个对象)。这就是委托模式的用途。它最大限度地减少了 MyObject 需要的信息(至少,只不过是一个指针类型id- 最好是由 MyObject 指定的协议,为它提供一些行为保证)

所以翻译你的例子

我的对象.h

代替...

-(id)initWithViewController:(ViewController*)aViewController;

和...

-(id) init; 

(如果您没有进一步的理由覆盖,您可以免除)

和...

@property (nonatomic, weak) id delegate;

myViewController 中的实例化(确实需要#include MyObject)...

MyObject* object = [[MyObject alloc] init];

其次是

object.delegate = self;

(请注意,object获取指向 myViewController 的指针而无需了解其他任何信息)

现在您可以从内部执行此操作object

 [self.delegate updateButtonValue:@"example"];

但是......您需要确保您的代表可以收到消息updateButtonValue

为此,您在 MyObject.h 中声明一个带有此方法签名的协议

@protocol MyObjectDelegate

  - (void) updateButtonValue:(NSString*)string;

@end

在您的 viewController 中,使用接口行中的 <> 声明您符合此协议

@interface ViewController <MyObjectDelegate>

(这没什么大不了的,ViewController 已经必须分配#include MyObject/初始化它,所以不需要更多信息来执行此操作)

并因此扩展您的财产声明:

@property (nonatomic, weak) id <MyObjectDelegate> delegate

现在您已经为编译器提供了足够的信息,以确保您只能传递一致的消息。这里的绝妙之处在于 MyObject 可以自信地将消息传递给 MyViewController,而不需要知道有关 MyViewController 的任何信息,除了通过委托指针到达它之外。

于 2013-02-14T03:21:45.363 回答