NSClassFromString不允许我设置委托

时间:2013-01-09 15:53:23

标签: uiviewcontroller delegates

我使用NSClassFromString来分配viewcontrollers。但这不会让我为自己设定代表。有可能吗?

nibString = @"ViewControllerName";
Class viewControllerClass = NSClassFromString( nibString );
loadedVC = (UIViewController*) [[viewControllerClass alloc] initWithNibName:nibString bundle:nil];
[loadedVC setDelegate:self];

最后一行报告“UIViewController”没有可见的@接口声明选择器'setDelegate'

我确信如果我通过属性分配vc它会起作用但我使用这种方法是为了方便 - 尽管我可以停止,如果我可以设置它的委托。

有人可以建议解决方案吗?

2 个答案:

答案 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:

相关问题