objective-c - 在 prepareForSegue 中传递对 ViewController 的引用

标签 objective-c ios cocoa-touch uiviewcontroller uistoryboardsegue

我有 2 个 View Controller ,分别称为 ViewController1 和 ViewController2。当我想加载 ViewController2 时,从 ViewController1 调用模态 segue。我在 ViewController1 中有一个方法,需要在 ViewController2 显示时调用。我的想法是在 ViewController2 中有一个属性是对 ViewController1 的引用,以便我可以访问该方法。

@property (strong, nonatomic) ViewController1 *vc1Reference;

该属性将在 prepareForSegue 方法中设置,如下所示:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {//1
if ([[segue identifier] isEqualToString:@"sequeToVC2"]) {//2
ViewController2 *vc2 = segue.destinationViewController;//3
vc2.vc1Reference = (ViewController1*)segue.sourceViewController;//4
}
}


但是第 4 行给了我这个错误: ARC 不允许将 Objective-C 指针隐式转换为“int *”。

我应该如何设置引用?

最佳答案

您走在正确的轨道上,但正确的方法是使用委托(delegate)。

您在 vc2 @interface 中声明了一个委托(delegate)属性:

@property (nonatomic, weak) id <vc2delegate> delegate   //[1] (in vc2.h)

并且您在 prepareForSegue 中设置了委托(delegate):
vc2.delegate = self;    //[2] (in vc1.m)

('self' 是 vc1 的正确引用,来自 vc1)

在 vc2 中定义一个协议(protocol),这是您期望 vc1 从 vc2 响应的方法。把它放在 vc2.h 中,在你的 @interface 上面
@protocol vc2delegate           //[3] (in vc2.h)
- (void) delegateMethod;
@end

然后你必须确保你在vc1中实现了那个方法。您还需要让 vc1 知道遵守委托(delegate)。将 vc2 导入 vc1.h,然后在您的 @interface 上vc1 中的行在尖括号中添加协议(protocol)名称:
#import vc2.h

@interface vc1 <vc2delegate>     //[4] (in vc1.h)

这种安排允许 vc2 将方法传递给 vc1 而不必 #include vc1 或知道其他任何事情。

更多详情...
  • 这是你的正确形式
    @property (strong, nonatomic) ViewController1 *vc1Reference;
    

    注意 weak 的使用引用。您不想制作 strong引用,因为您真的不想与委托(delegate)有任何关系,除非知道它可以处理您在协议(protocol)中指定的方法。委托(delegate)通常是创建委托(delegate)的对象,创建一个 strong反向引用可能会导致内存泄漏,因为两个对象都不会消失。
  • 这是您的行的正确形式:
    vc2.vc1Reference = (ViewController1*)segue.sourceViewController;
    

    请注意,我们没有在 1 或 2 中使用类型/强制转换。为了最大程度地重用代码/解耦,我们不想对 segue 两端的对象类型做出任何假设。
    我假设您的“prepareForSegue”在 vc1 中。如果不是,那么该行将如下所示:
    vc2.delegate = segue.sourceViewController
    
  • 这是协议(protocol)声明。它位于 vc2 的头文件中。 vc2 正在发布它对选择成为其委托(delegate)的任何对象的期望。 vc2 将根据此协议(protocol)发送消息,因此任何委托(delegate)都需要以正确的方式响应。您可以通过使用这种消息传递来防止 vc2 中的故障
    if (self.delegate respondsToSelector:@selector('delegateMethod')
    {
        [self.delegate delegateMethod];
    }
    

    (这是在 vc2 中用于与 vc1 通信的消息传递示例。显然,如果需要,您可以传递参数并返回返回的结果)
  • 这是编译器的助手,如果您未能实现协议(protocol),它会向您发出警告。

    最后,在您的对象定义中的某个地方,您需要实现该方法:
    - (void) delegateMethod 
    {
        // someaction;
    }
    
  • 关于objective-c - 在 prepareForSegue 中传递对 ViewController 的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14228191/

    相关文章:

    iphone - 如何制作 "shaking"动画

    ios - 框架的字符串本地化

    iOS Swift 3 - 提交后无法停止 UIActivityIndi​​catorView

    ios - UIWindow 的目的是什么?

    iphone - 在 imageView.tag 中存储 25 位数字字符串

    iphone - 核心数据一对多关系: List all related objects as section header in UITableView

    iphone - 自定义字体不以大写字母显示分音符

    iphone - 为 iphone HTTP API 添加自定义证书

    objective-c - XCode 构建结果 : why is it so amazingly complex even for a hello world console app?

    ios - 解析json并用tableview显示