我正在制作主细节应用程序,我有动态Detail ViewController。细节ViewController已更改。
但是在每个Detail ViewController中我都有一个常用的方法updateInfo
我想调用那个方法
这是我的代码
UINavigationController *nav=[self.splitViewController.viewControllers objectAtIndex:1];
UIViewController *controller=[nav.viewControllers objectAtIndex:0];
[controller updateLastInfo];
但它给了我错误没有找到方法。
如果我使用UIViewController名称,它将起作用。
HomeViewController *controller=(HomeViewController)[nav.viewControllers objectAtIndex:0];
[controller updateLastInfo];
但我不想做上面的事情。
我试图解释一下。请帮忙
答案 0 :(得分:1)
您可以使用id
UINavigationController *nav=[self.splitViewController.viewControllers objectAtIndex:1];
id controller=[nav.viewControllers objectAtIndex:0];
[controller updateLastInfo];
答案 1 :(得分:1)
您可以创建UIViewController
的子类并创建一个基本DetailViewController
类,其中包含详细视图控制器的常用功能。然后,您将使所有详细视图控制器成为子类DetailViewController
而不是UIViewController
。这将是一种安全的方法,并且还允许您在特定详细信息视图控制器中为updateInfo
方法添加额外功能。
如果您想要一种不安全的方法,可以使控制器对象的类型为id
。我不会建议这种方法,因为它依赖于您对代码的个人知识。如果其他人(或者你自己在路上)将它设置为没有该方法的视图控制器,代码仍将尝试运行并将崩溃。
答案 2 :(得分:1)
UIViewController
没有一个名为updateInfo
的方法,因此当您尝试将该消息发送到只知道指向的指针时编译器会抱怨UIViewController
的一个实例。当您使用类名时,如下所示:
HomeViewController *controller=(HomeViewController)[nav.viewControllers objectAtIndex:0];
您正在向编译器提供更多信息,使用类型转换来告诉它"嘿,不要担心,我肯定知道我回来的对象是一个HomeViewController
。由于您似乎有几种类型的视图控制器都具有此方法,因此最好的做法是在协议中声明updateInfo
方法,然后让每个UIViewController
子类实现该协议。因此,您的协议声明将位于头文件中,可能如下所示:
@protocol SomeProtocol
- (void)updateInfo
@end
并且每个具有-updateInfo
方法的类只需要声明它采用协议:
@interface HomeViewController <SomeProtocol>
//...
@end
然后确保您的班级实施中有-updateInfo
:
@implementation HomeViewController
- (void)updateInfo {
//...
}
//...
@end
然后,在您的代码中,您可以使用-conformsToProtocol:
检查对象是否符合协议:
if ([controller conformsToProtocol:@protocol(SomeProtocol)]) {
UIViewController<SomeProtocol> *c = (UIViewController<SomeProtocol>*)controller;
[c updateInfo];
}
或者在调用之前检查对象是否响应选择器:
if ([controller respondsToSelector:@selector(updateInfo)]) {
[controller performSelector(updateInfo)];
}
您收到的其他答案(使用id
或创建公共基类)也很好,但为了安全起见,请确保在调用方法之前进行一些检查。例如,您可以使用-isKindOfClass
来确保您获得的视图控制器实际上是您的公共基类的实例,并且您可以使用上面的-respondsToSelector:
来检查{{1}指向实现id
的对象。