Objective-C:你可以testing静态类types的未初始化的指针吗?

我正在尝试做一些事情:

在一些物体A:

UITableVIewController *viewController; [someObjectB setupView: viewController]; 

在一些物体B:

 -(void) setupView:(UIViewController*)view { if the pointer passed in is of type UITableViewController then ... say, for instance with: [[view class] isKindOfClass [UITableViewController class]] or: [view isKindOfClass [UITableViewController class]] } 

但是,我有两个问题:首先,参数作为UITableView(我正在做,因为这个方法也会configuration其他types的视图控制器)的超类UIViewController进入B方法的事实。 所以我想知道,如果我将UITableViewController传递给types为UIViewController的方法参数,isKindOfClass仍然会dynamic绑定吗? 也就是说,运行时检查内容的types,而不pipe指针的静态types如何?

其次,请注意,在传递给B之前,我没有初始化对象A中的指针。实际上,我希望B初始化它。 但是后来buy的问题就变成了,我怎么testing一个未初始化的指针上的静态指针types呢? 也就是在B里面:[view isKindOfClass [UITableViewController class]]给了我一个BAD_EXEC。 我的猜测,因为我显然是试图访问一个JUL指针。 那么还有一种方法可以根据指针的静态types声明来进行testing吗?

附加:(因为我把它添加为一个评论,而不是,对不起)

让我用更具体的术语来重新说明这个问题的一部分:我想obj B创build一个UITableViewControllertypes的variables,将它传递给A,并且A意识到它被赋予了一个指向UITableViewController的指针,以便它实际上可以初始化这个指针UITableViewController的一个特定的子类,然后obj B将该对象初始化为其他对象。

我想要做到这一点的理由是以下情况:我有一个基于导航控制器的应用程序。 它有一个带有button的根控制器,根据哪个button被按下,根控制器实例化并推送表控制器用于数据库的不同表,并且当点击这些表的一行时,表实例化并推送详细的视图控制器。

到目前为止这么好,但由于项目的性质,我想保持整个navigationcontroller实例化推链不可知的事实,有一个数据库,表和详细视图控制器实际上是UITableViewController和UIViewController的具体子类, 分别。

这意味着stream程将是:

1-在点击时,根控制器将通用UIViewController传递给我的自定义主控制器。

2 – 这个主控制器意识到它已经通过了一个generics表,将其初始化为由我定义的特定子类,并执行一些事情来为其提供来自sql数据库的数据。

3 – 根控制器,不关心genericsUIViewController是否是一个表,或者甚至是UIViewController的子类,只是把它推到navigationController。

这个想法也是,那么我不需要在根控制器中包含表子类的头文件。 只有自定义的主控制器知道这些。

所以,在一天结束的时候,我看到的做法是通过能够确定被传递的指针的types是什么,而不pipe这个指针是否为零,指向垃圾或指向实际的对象。 含义:

UIVIewController * a – >静态types声明,在编译时确定。

a = [UIVIewController alloc的一些子类] init]; – >指针的内容的dynamictypes,在运行时确定,可能通过以下链接通过激活logging..类似于C ++中的“虚拟”

正如其他人所指出的,你所要求的是不可能的。 当您将一个variables传递给一个方法时,它只发送该值,而不是该types。 另外,运行时并不知道方法中variables的types。 任何variablestypes的处理都由编译器完成。 运行时只能知道variables持有的对象的类。

或者,如果您可以更改方法的签名,则可以添加一个指示要创build的对象types的参数。 调用方法仍然不需要知道对象的确切types,不pipe它是否是表视图控制器。 这是一个使用枚举来保存不同types的例子。

 // header enum ViewControllerType { ViewControllerNormal = 0, ViewControllerTableView }; - (void)setupView:(UIViewController **)view ofType:(enum ViewControllerType)type; // implementation - (void)setupView:(UIViewController **)view ofType:(enum ViewControllerType)type { if(!view) { NSLog(@"setupView:ofType: received nil pointer"); return; } switch(type) { case ViewControllerNormal: // create normal UIViewController type break; case ViewControllerTableView: // create UITableViewController type break; default: NSLog(@"setupView:ofType: received unknown type: %i",type); return; } } 

用于:

 UIViewController *view; [creatorObject setupView:&view ofType:ViewControllerNormal]; // or UITableViewController *tableView; [creatorObject setupView:&tableView ofType:ViewControllerTableView]; 

Objective-C是一种按值传递的语言,就像C.你不能在你的对象A中用你有的代码初始化viewController 。 初始化它,将它的地址传递给setupView:然后根据需要初始化它:

 UITableVIewController *viewController = nil; [someObjectB setupView:&viewController]; 

和:

 -(void)setupView:(UIViewController**)view { if (*view == nil) // initialize it - *view = [[blah alloc] init] or whatever else ... } 

在回答你的第一个问题时,是的 – Objective C将在运行时(dynamic)确定对象的类types。 在回答你的第二个问题时,任何派发给nil对象的方法调用都会被忽略,所以你的类检查都不会真正起作用。 你不应该得到一个BAD_EXEC,除非你:

  • 之前初始化对象并释放它,但不设置为零,导致其内存地址出现垃圾
  • 传递给由编译器为您创build的未初始化的自动variables
  • 无论出于何种原因,将其指向记忆中的某个无意义的地址。

*编辑*

添加了一个你将得到一个BAD_EXEC的场景,同时,在下面的链接中也可以看到一些关于类相等性testing的问题,特别是使用isKindOfClass方法。

在Objective-C中,Java的“instanceof”关键字是什么?