Ios (类)类的含义是什么?

Ios (类)类的含义是什么?,ios,objective-c,Ios,Objective C,这是我的示例代码: View *v1 = [View new]; NSLog(@"%d",([v1 isKindOfClass:[View class]])); NSLog(@"%d",([[v1 class] isKindOfClass:[View class]])); View是一个类,现在我有些困惑: v1是View的实例,View是View的元类的实例,对吗 [v1类]的返回值是一个名为isa指向类对象的指针,对吗 [View class]的返回值是一个名为isa指向元类的指针,对吗

这是我的示例代码:

View *v1 = [View new];
NSLog(@"%d",([v1 isKindOfClass:[View class]]));
NSLog(@"%d",([[v1 class] isKindOfClass:[View class]]));
View
是一个类,现在我有些困惑:

  • v1是View的实例,View是View的元类的实例,对吗
  • [v1类]
    的返回值是一个名为
    isa
    指向类对象的指针,对吗
  • [View class]
    的返回值是一个名为
    isa
    指向元类的指针,对吗
  • 我记录了
    [v1类]
    [View类]
    的地址,它们是相等的,为什么

    NSLog(@"%p", [v1 class]);
    NSLog(@"%p", [View class]);
    
    2018-01-05 10:47:30.554190+0800 Block[16532:785147] 0x10a61a178
    2018-01-05 10:47:30.554300+0800 Block[16532:785147] 0x10a61a178
    
    NSLog(@"%p", [v1 class]);
    NSLog(@"%p", [View class]);
    
    2018-01-05 10:47:30.554190+0800 Block[16532:785147] 0x10a61a178
    2018-01-05 10:47:30.554300+0800 Block[16532:785147] 0x10a61a178
    
  • 我想关键点是
    [View class]
    的返回值,所以如果
    [View class]
    的返回值没有指向它的元类,那么它是谁??它指的是谁

  • 编辑

    我从apple文档中获得了一些信息,两个方法的返回值相同,名为
    类对象
    ,这是什么?元类的实例??如何获得元类

  • v1是View的实例,View是View的元类的实例,对吗
  • v1
    视图的一个实例

    不能将
    View
    用作常规的C标识符,只能用作类消息的接收者(如
    [View new]
    ),但有一个真正的对象接收这些类消息。调用
    视图
    类对象是常见且方便的,它是
    视图
    元类的唯一实例

  • [v1类]
    的返回值是一个名为
    isa
    指向类对象的指针,对吗
  • [v1类]
    返回对
    视图
    类对象的引用。
    isa
    “指针”是一个实现细节,实际上它的实现已经改变了。看

  • [View class]
    的返回值是一个名为
    isa
    指向元类的指针,对吗
  • [View class]
    的意思与
    [View self]
    完全相同。两者都返回
    视图
    类对象,而不是元类对象。你可以从中看到这一点。我将在这里引用相关的方法定义

    + (id)self {
        return (id)self;
    }
    
    当您说
    [View self]
    时,它运行上面引用的
    +[NSObject self]
    方法,局部变量
    self
    指向
    视图
    类对象。(哇,这是很多“self”!)因此
    [View self]
    返回
    视图
    类对象:

    - (id)self {
        return self;
    }
    
    当你说
    [v1 self]
    时,它运行上面引用的
    -[NSObject self]
    方法,局部变量
    self
    指向
    v1
    对象(一个
    视图
    实例)。所以
    [v1 self]
    返回
    v1

    + (Class)class {
        return self;
    }
    
    当您说
    [View class]
    时,它运行上面引用的
    +[NSObject class]
    方法,局部变量
    self
    指向
    视图
    类对象。因此
    [View class]
    返回
    视图
    类对象,就像
    [View self]
    一样

    - (Class)class {
        return object_getClass(self);
    }
    
    当你说
    [v1 class]
    时,它运行上面引用的
    -[NSObject class]
    方法,局部变量
    self
    指向
    v1
    对象(一个
    视图
    实例)。此方法与上述其他三种方法的主体不同。此方法使用Objective-C运行时函数
    object\u getClass
    获取对
    视图
    类对象的引用

  • 我记录了[v1类]和[View类]的地址,它们是相等的,为什么

    NSLog(@"%p", [v1 class]);
    NSLog(@"%p", [View class]);
    
    2018-01-05 10:47:30.554190+0800 Block[16532:785147] 0x10a61a178
    2018-01-05 10:47:30.554300+0800 Block[16532:785147] 0x10a61a178
    
    NSLog(@"%p", [v1 class]);
    NSLog(@"%p", [View class]);
    
    2018-01-05 10:47:30.554190+0800 Block[16532:785147] 0x10a61a178
    2018-01-05 10:47:30.554300+0800 Block[16532:785147] 0x10a61a178
    
  • 如上所述,这两个函数都返回
    视图
    类对象

  • 我猜关键点是[View class]的返回值,所以如果[View class]的返回值不指向它的元类,那么它是谁??它指的是谁
  • [View class]
    返回与
    [View self]
    相同的内容:
    视图
    类对象。如果要获取对
    视图
    元类对象的引用,需要直接使用Objective-C运行时,如下所示:

    NSLog(@"%p", object_getClass([View class]));
    
    请注意,如果使用
    %@
    打印
    [View class]
    ,它只打印
    视图
    。如果您使用
    %@
    打印
    对象_getClass([View class])
    ,它也只打印
    视图
    。不能通过字符串描述区分
    视图
    类对象和
    视图
    元类对象。您必须查看指针值(这确实是您所做的)

    这是我的测试:

    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    
    @interface View: NSObject
    @end
    
    @implementation View
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            View *v1 = [View new];
            NSLog(@"v1 = %@ / %p", v1, v1);
            NSLog(@"[v1 class] = %@ / %p", [v1 class], [v1 class]);
            NSLog(@"[[v1 class] class] = %@ / %p", [[v1 class] class], [[v1 class] class]);
            NSLog(@"[View class] = %@ / %p", [View class], [View class]);
            NSLog(@"object_getClass([View class]) = %@ / %p", object_getClass([View class]), object_getClass([View class]));
        }
        return 0;
    }
    
    因此:

    • 我的
      v1
      对象位于0x101600780
    • 视图
      类对象位于0x1000011e0
    • 视图
      元类对象位于0x1000011b8
    您可能想知道为什么
    [View class]
    返回
    视图
    类对象而不是
    视图
    元类对象。Greg Parker是维护Objective-C运行时的主要苹果员工,他解释了原因:

    Objective-C使用元类实现类方法等实际目标,但在其他方面往往隐藏元类。例如,
    [NSObject class]
    [NSObject self]
    相同,尽管在形式上它应该返回
    NSObject->isa
    指向的元类。Objective-C语言是一套实用的折衷方案;在这里,它限制了类模式,以免它变得太元

  • v1是View的实例,View是View的元类的实例,对吗
  • v1
    视图的一个实例

    不能将
    View
    用作常规的C标识符,只能用作类消息的接收者(如
    [View new]
    ),但有一个真正的对象接收这些类消息。调用
    视图
    类对象是常见且方便的,它是
    视图
    m的唯一实例