0

我猜标题本身就足以解决我的问题。但是我将在这里进一步解释,考虑我有两个视图控制器 A 和 B。A 是基础并且它正在推动 B,在一种情况下,我希望在视图 (B) 中单击一个按钮时从 B 提示 A。如果我有那个实例,目标 C 允许直接调用 A 视图。我认为这样做不是一个好习惯。这种情况应该怎么处理。。

谢谢你的建议。

4

1 回答 1

2

如果'A从B暗示'你的意思是你想调用最初负责推动B的A,你只需使用'返回'按钮或在代码中返回A:

[self.navigationController popViewController animated:YES];

B 不需要指向 A 的指针,导航控制器有,而 B 有指向导航控制器的指针,因为导航控制器navigationController在创建 B 时设置了 B 的属性。

如果您需要基于 B 中的某些操作在 A 中设置属性,则应使用委托来执行此操作。

在 B 中,您创建了一个名为 的属性delegate

在 A 中,当您创建 B 时,将它的委托设置为 A:

ViewControllerB* vcB = [[ViewControllerB alloc] init];
vcB.delegate = self;
[self.navigationController pushViewController:vcB];

然后在 B 中,您可以在弹出之前通过委托回调 A:

[self.delegate sendMessageWithValue:someValue];
[self.navigationController popViewController animated:YES];

如果您想格外小心,可以将消息传递附上:

if ([self.delegate respondsToSelector:@selector(sendMessageWithValue:)]) { ... }

为了在 B 不知道任何关于 A 的情况下完成这项工作,除了它是委托之外,B 应该在标头中声明一个委托协议(上图@interface

@protocol BDelegateProtocol
- (void) sendMessageWithValue:(int)someValue;
@end

当您delegate在 B's 中声明该属性时@interface,请指定它应遵循的协议:

@property (nonatomic, weak) id <BDelegateProtocol> delegate;

在 A 的 @interface 标头中,宣传您遵循该协议:

#import BViewController;

@interface AViewController:UIViewController <BDelegateProtocol>

这就是您所追求的松散耦合。B 不必导入 A 的标头。除了符合 B 的协议规范之外,它不需要知道关于 A 的任何信息。

B 确实持有指向 A 的指针,但它是一个指针。这个非常重要。如果委托属性是strong,则 B 会将其委托的保留计数增加 1。如果委托持有指向 B 的强指针,则它们都不会被释放。当 A 存在时,B 的保留计数始终至少为 1,同样,当 B 存在时,A 的保留计数始终为 1:两者都不能被销毁。

在这种可能不会发生的特殊情况下 - A 不需要像 Nav Controller 那样保留 B - 但这种情况经常出现,因为委托通常是创建和拥有委托人的对象。请参阅 Apple实用内存管理中的“使用弱引用来避免保留周期”

于 2013-01-17T09:35:47.513 回答