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”关键字是什么?