我有2个视图控制器,称之为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 *'。
我该如何设置参考?
答案 0 :(得分:3)
您走在正确的轨道上,但正确的方法是使用委托。
您在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响应的方法。将它放在vc2.h中,高于@interface
@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或了解其他任何内容。
更多细节...
这是
的正确形式@property (strong, nonatomic) ViewController1 *vc1Reference;
请注意使用weak
引用。您不希望创建strong
引用,因为您不希望与委托有任何关系,除非知道它可以处理您在协议中指定的方法。委托通常是创建委托者的对象,在另一个方向上创建strong
引用会导致内存泄漏,因为这两个对象都不会存在。
这是您的行的正确形式:
vc2.vc1Reference = (ViewController1*)segue.sourceViewController;
请注意,我们不是在1或2中使用类型/强制转换。为了最大限度地重用代码/解耦,我们不想对segue任何一端的对象类型做出任何假设。 我假设你的'prepareForSegue'在vc1中。如果不是那么该线看起来像这样:
vc2.delegate = segue.sourceViewController
这是协议声明。它位于vc2的头文件中。 vc2正在发布它对任何选择成为其委托的对象的期望。 vc2将根据此协议发送消息,因此任何委托都需要以正确的方式响应。您可以使用这种消息传递来防止vc2中的失败
if (self.delegate respondsToSelector:@selector('delegateMethod')
{
[self.delegate delegateMethod];
}
(这是您在vc2中用于与vc1进行通信的消息传递类型的示例。如果需要,您可以显然传递参数并返回返回结果)
这是编译器的帮助程序,如果您未能实现协议,它可以向您发出警告。
最后在对象定义的某处,您需要实现该方法:
- (void) delegateMethod
{
// someaction;
}
答案 1 :(得分:1)
前几天我遇到了类似的事情。我最终为vc2创建了一个委托,并使用
vc2.delegate = self;
而不是在segue中。这会解决你的问题吗?如果您需要帮助设置代表,请告诉我,我会尽力帮助您!
答案 2 :(得分:0)
只需将一个委托添加到您正在访问该委托的ViewController上,之后XCode / Obj-C似乎做了正确的事。
在:
@interface ViewController2 : UIViewController
@end
后:
@interface ViewController2 : UIViewController
@property (nonatomic, weak) id <UIPageViewControllerDelegate> delegate;
@end