我使用NSClassFromString来分配viewcontrollers。但这不会让我为自己设定代表。有可能吗?
nibString = @"ViewControllerName";
Class viewControllerClass = NSClassFromString( nibString );
loadedVC = (UIViewController*) [[viewControllerClass alloc] initWithNibName:nibString bundle:nil];
[loadedVC setDelegate:self];
最后一行报告“UIViewController”没有可见的@接口声明选择器'setDelegate'
我确信如果我通过属性分配vc它会起作用但我使用这种方法是为了方便 - 尽管我可以停止,如果我可以设置它的委托。
有人可以建议解决方案吗?
答案 0 :(得分:2)
我假设你已经宣布loadedVC
这样:
UIViewController *loadedVC;
编译器只允许您向其发送它知道属于UIViewController
的{{1}}的消息。这是一件好事。它可以防止大量运行时错误。但有时你比编译器更清楚,并且想要关闭@interface
检查。
当您尝试将消息发送到类型@interface
的值时,编译器不会检查消息,因为id
是没有id
的泛型类型。所以将@interface
投射到loadedVC
:
id
请注意,如果[(id)loadedVC setDelegate:self];
没有(或继承)loadedVC
方法,则会出现运行时错误。如果您想先检查方法,请尝试以下方法:
setDelegate:
另一种方法是创建一个包含if ([loadedVC respondsToSelector:@selector(setDelegate:)]) {
[(id)loadedVC setDelegate:self];
}
方法的协议:
setDelegate:
然后你可以像这样声明@protocol HasDelegate
- (void)setDelegate:(id)delegate;
@end
告诉编译器它符合协议:
loadedVC
现在,当您尝试将UIViewController<HasDelegate> *loadedVC;
发送到setDelegate:
时,编译器不会抱怨(即使没有强制转换)。但如果loadedVC
实际上没有loadedVC
方法,您仍会收到运行时错误。
答案 1 :(得分:1)
UIViewControler类没有委托属性。通常将视图控制器设置为视图的委托,因此将在视图上调用setDelegate,而不是控制器。
如果你有一个支持委托的视图控制器子类,那么编译器将无法看到它,因为你的loadedVC引用已被强制转换为UIViewControler。如果这是问题,有几种解决方案。
1)您可以强制转换为使用的类,或者实现委托的第一个超类。
2)您可以使用正式或非正式协议。
3)您可以调用respondsToSelector:,然后调用performSelector:withObject:
等