Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C:能否测试静态类类型的未初始化指针?_Objective C_Ios_Cocoa_Pointers_Null - Fatal编程技术网

Objective-C:能否测试静态类类型的未初始化指针?

Objective-C:能否测试静态类类型的未初始化指针?,objective-c,ios,cocoa,pointers,null,Objective C,Ios,Cocoa,Pointers,Null,我正试图按照以下思路做一些事情: 在某些对象中: 在某些对象B中: 然而,我有两个问题: 首先,参数以UIViewController的形式输入B中的方法,这是UITableView的超类(我这样做是因为此方法还将配置其他类型的视图控制器)。所以我想知道,若我将UITableViewController传递给UIViewController类型的方法参数,那个么类的kindof是否仍然具有动态绑定权限?也就是说,运行时检查内容的类型,而不考虑指针的静态类型 其次,请注意,在将对象A中的指针传递给

我正试图按照以下思路做一些事情:

在某些对象中: 在某些对象B中: 然而,我有两个问题: 首先,参数以UIViewController的形式输入B中的方法,这是UITableView的超类(我这样做是因为此方法还将配置其他类型的视图控制器)。所以我想知道,若我将UITableViewController传递给UIViewController类型的方法参数,那个么类的kindof是否仍然具有动态绑定权限?也就是说,运行时检查内容的类型,而不考虑指针的静态类型

其次,请注意,在将对象A中的指针传递给B之前,我没有初始化它。实际上,我希望B初始化它。但问题是,如何在未初始化的指针上测试静态指针类型?也就是说,在B内部:[view iskindof类[UITableViewController类]]给了我一个错误的执行。我猜,因为我显然是想接近七月指针。那么,有没有一种方法仍然可以基于指针静态类型声明进行测试

附录:(因为我添加了它作为评论,抱歉) 让我用更具体的术语来重新表述问题的这一部分:我想让obj B创建一个UITableViewController类型的变量,将其传递给a,并让a意识到它被赋予了一个指向UITableViewController的指针,因此,它实际上可以初始化这个指向UITableViewController的特定子类的指针,然后obj B将现在初始化的对象传递给其他对象

我想这样做的原因如下: 我有一个基于navigationController的应用程序。它有一个带有按钮的根控制器,根控制器根据按下哪个按钮,为数据库的不同表实例化并推送表控制器,反过来,当单击这些表中的一行时,表实例化并推送详细视图控制器

到目前为止还不错,但由于项目的性质,我想让整个navigationcontroller实例化推送链不可知,因为有一个数据库,表和详细视图控制器实际上分别是UITableViewController和UIViewController的特定子类

这意味着流量将为:

1-单击后,根控制器将通用UIViewController传递给我的自定义主控制器

2-这个主控制器意识到它被传递了一个通用表,将它初始化为我定义的一个特定子类,并做了一些事情来为它提供来自sql数据库的数据

3-根控制器不关心通用UIViewController是否为表,甚至不关心UIViewController的子类,只将其推送到navigationController

这样,我就不需要在根控制器中包含表子类的头了。只有自定义主控制器知道这些

因此,在一天结束时,我看到的方法是通过能够确定所传递的指针的类型,而不管该指针是nil、指向垃圾还是指向实际对象。意思是:

UIVIewController*a->静态类型声明,在编译时确定


a=[UIVIewController alloc的某些子类]init];->指针内容的动态类型,在运行时确定,可能通过激活记录中的链接来确定。。与C++中的“虚拟”类似,Objective-C是一种传递值语言,与C类似。您不能使用对象a中的代码初始化视图控制器。初始化它,将其地址传递到
设置视图:
,然后根据需要初始化它:

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


在回答第一个问题时,是-Objective C将在运行时(动态)确定对象的类类型。在回答第二个问题时,任何发送到nil对象的方法调用都会被静默忽略,因此您的类检查都不会真正起作用。但是,除非您:

  • 之前初始化了对象,并在未设置为nil的情况下释放它,导致其内存地址出现垃圾
  • 传入由创建的未初始化自动变量 为您准备的编译器
  • 不管出于什么原因,我把它指向了内存中某个毫无意义的地址

*编辑*

添加了一个场景,在该场景中,您将得到一个坏的_EXEC,另外,请参阅下面的链接,了解测试类平等性时的几个问题,特别是使用
isKindOfClass
方法


正如其他人所指出的,你所要求的是不可能的。将变量传递给方法时,它只发送值,而不发送类型。此外,运行时不知道方法中变量的类型。任何变量类型处理都由编译器完成。运行时只能知道变量所持有的对象的类

作为替代方案,如果可以更改方法的签名,则可以添加一个指示要创建的对象类型的参数。调用方法仍然不需要知道对象的确切类型,只需要知道它是否是表视图控制器。下面是一个使用枚举来保存不同类型的示例

// 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];

如果所传递的变量是自动变量,而不是实例变量,那么它实际上是未初始化的,可以是任何随机(或不太随机)位模式。我从来没有听说过
BAD\u EXEC
。你是说
EXC\u BAD\u ACCESS
?是的。正如从OP的问题中抄袭的。是的,我想我误读了。在任何情况下,OP都无法从未初始化(或初始化为nil)指针获取所需的信息。如果他试图在调用者中识别指针的类型,以便在被调用者中用特定类型的对象初始化它,那是不可能的
-(void)setupView:(UIViewController**)view
{
   if (*view == nil)
      // initialize it  - *view = [[blah alloc] init] or whatever
   else
       ...

}
// 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];