【问题标题】:Pass a reference to ViewController in prepareForSegue在 prepareForSegue 中传递对 ViewController 的引用
【发布时间】:2012-12-23 02:03:02
【问题描述】:

我有 2 个视图控制器,分别称为 ViewController1 和 ViewController2。当我想加载 ViewController2 时,从 ViewController1 调用模态序列。我在 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 *”。

我应该如何设置参考?

【问题讨论】:

  • 是的,我将 prepareForSegue 放在视图控制器 1 中。
  • 你在viewController2#import ViewController1做吗?

标签: objective-c ios cocoa-touch uiviewcontroller uistoryboardsegue


【解决方案1】:

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

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

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

你在你的prepareForSegue中设置了代理:

vc2.delegate = self;    //[2] (in vc1.m)

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

在 vc2 中定义一个协议,这是您期望 vc1 从 vc2 响应的方法。把它放在你的@interface上方的vc2.h中

@protocol vc2delegate           //[3] (in vc2.h)
- (void) delegateMethod;
@end

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

#import vc2.h

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

这种安排允许 vc2 将方法传递给 vc1,而不必#include vc1 或知道任何关于它的信息。

更多细节...

  1. 这是你的正确形式

    @property (strong, nonatomic) ViewController1 *vc1Reference;
    

    注意weak 引用的使用。您不想创建 strong 引用,因为您真的不想与委托有任何关系,除非知道它可以处理您在协议中指定的方法。委托通常是创建委托的对象,在另一个方向创建 strong 引用会导致内存泄漏,因为这两个对象都不会消失。

  2. 这是你的行的正确形式:

    vc2.vc1Reference = (ViewController1*)segue.sourceViewController;
    

    请注意,我们没有在 1 或 2 中使用类型/强制转换。为了最大程度地重用代码/解耦,我们不想对 segue 两端的对象类型做出任何假设。 我假设您的“prepareForSegue”在 vc1 中。如果不是,那么该行将如下所示:

    vc2.delegate = segue.sourceViewController
    
  3. 这是协议声明。它位于 vc2 的头文件中。 vc2 正在发布它对选择成为其委托的任何对象的期望。 vc2 将根据此协议发送消息,因此任何委托都需要以正确的方式响应。您可以通过使用这种消息传递来防止 vc2 中的失败

    if (self.delegate respondsToSelector:@selector('delegateMethod')
    {
        [self.delegate delegateMethod];
    }
    

    (这是您将在 vc2 中用于与 vc1 通信的消息传递示例。显然,您可以传递参数并在需要时返回返回的结果)

  4. 这是编译器的助手,如果您未能实现协议,它会向您发出警告。

    最后在你的对象定义的某个地方你需要实现这个方法:

    - (void) delegateMethod 
    {
        // someaction;
    }
    

【讨论】:

  • 您的意思是在 vc1 @interface 中声明 @property (nonatomic, weak) id &lt;vc2delegate&gt; delegate 吗?
  • 他没有,应该在vc2里。这样,vc2 可以使用 [self.delegate delegateMethod];调用函数(在本例中,是您尝试在 vc1 中调用的函数)。
  • 好吧好吧。另外,他让vc1知道遵守委托是什么意思?
  • 我猜这意味着在@interface vc1中有
  • 谢谢你们俩!一切都按预期工作。我的最后一个错误是由于循环导入。
【解决方案2】:

前几天我遇到了类似的事情。我最终为 vc2 创建了一个委托,并使用了

vc2.delegate = self;

改为在 segue 中。这会解决你的问题吗?如果您在设置代理时需要帮助,请告诉我,我会尽力提供帮助!

【讨论】:

    【解决方案3】:

    只需将一个委托添加到您正在访问委托的 ViewController,XCode / Obj-C 之后似乎做了正确的事情。

    之前:

    @interface ViewController2 : UIViewController
    
    @end
    

    之后:

    @interface ViewController2 : UIViewController
      @property (nonatomic, weak) id <UIPageViewControllerDelegate> delegate;
    @end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多