美文网首页
iOS之id和NSObject *的区别

iOS之id和NSObject *的区别

作者: 无极战思 | 来源:发表于2020-10-16 20:32 被阅读0次

    1.idobjc.h中定义

      typedef struct objc_class *Class;
      typedef struct objc_object {
      Class isa;
      } *id;
    

    从上面可以看出,id本质是struct objc_object结构体指针,可以指向任何OC对象。
    注意:这里说的是指向OC对象,像int、NSInteger这些基本数据类型可以的,将id指向int会报错

    image.png

    OC中的基类除了NSObject之外,还有一个NSProxy虚类。因此,id相比NSObject *指向的对象范围要更广

    2.id动态数据类型,而NSObject *静态数据类型,默认情况下所有的数据类型都是静态

    • id类型的实例在编译阶段不会做类型检查,会在运行时确定,而类NSObject的实例在编译期要做编译检查,保证指针指向是其NSObject类或其子类,当然,实例的具体类型也要在运行时才能确定,这也就是iOS三大特性之一的多肽

    • 静态类型编译时就知道变量的类型,编译时就知道变量的类型,在编译的时候就可以访问对象的属性方法,如果访问了不属于静态类型的属性方法,那么编译器就会报错,而动态数据类型编译的时候并不知道变量的真实类型,只有在运行时的时候才知道它的真实类型,因此编译时候如果访问了不属于动态类型的属性方法,编译器不会报错,导致运行时的错误,这也是动态数据类型弊端
      举例如下:

      #import <Foundation/Foundation.h>
      NS_ASSUME_NONNULL_BEGIN
      @interface People : NSObject
      -(void)eatFood;
      @end
      NS_ASSUME_NONNULL_END
      #import "People.h"
      @implementation People
      -(void)eatFood
       {
       NSLog(@"eatFood");
       }
       @end
      
      
      
      #import "ViewController.h"
      #import "People.h"
      @interface ViewController ()
      
      @end
      @implementation ViewController
      
      -(void)drinkWater
      {
      NSLog(@"drinkWater");
      }
      - (void)viewDidLoad {
      [super viewDidLoad];
      id test = [People new];
      [test drinkWater];
      // Do any additional setup after loading the view.
      }
      @end
      

    从上面代码我们不难看出,drinkWater方法并不是id指针指向对象的方法,调用了不是自己的方法,但是编译没有报错,只有运行时才报错了。

    相关文章

      网友评论

          本文标题:iOS之id和NSObject *的区别

          本文链接:https://www.haomeiwen.com/subject/cuctmktx.html