ios - -(Class)class 是什么意思?

标签 ios objective-c

这是我的示例代码:

View *v1 = [View new];
NSLog(@"%d",([v1 isKindOfClass:[View class]]));
NSLog(@"%d",([[v1 class] isKindOfClass:[View class]]));

View 是一个类,现在我有些困惑:

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

    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
    
  5. 我猜重点是[View class]的返回值,所以如果[View class]的返回值没有指向它的元类,它是谁??它指向谁??

编辑

我从苹果文档中得到了一些信息,type method of -classinstance method of class ,这两个方法有相同的返回值,名为class object,这是什么?元类的实例??以及如何获取元类?

最佳答案

  1. v1 is an instance of View, and View is an instance of View's meta class, right?

v1View 的实例。

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

  1. return value of [v1 class] is an pointer named isa point to class object, right?

[v1 class] 返回对 View 类对象的引用。 isa“指针”是一个实现细节,实际上它的实现已经改变了。参见 “Non-pointer isa” .

  1. return value of [View class] is an pointer named isa point to meta class, right?

[View class][View self] 的含义完全相同。两者都返回 View 类对象,而不是元类对象。你可以在 the Objective-C runtime source code 中看到这个.我会在这里引用相关的方法定义。

+ (id)self {
    return (id)self;
}

当你说[View self]时,它运行上面引用的+[NSObject self]方法,局部变量self指向到 View 类对象。 (哇,有很多“self”!)因此 [View self] 返回 View 类对象:

- (id)self {
    return self;
}

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

+ (Class)class {
    return self;
}

当你说[View class]时,它运行上面引用的+[NSObject class]方法,局部变量self指向到 View 类对象。所以 [View class] 返回 View 类对象,就像 [View self] 一样。

- (Class)class {
    return object_getClass(self);
}

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

  1. I log address of [v1 class] and [View class], they are equal, why?

    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 类对象。

  1. I guess the key point is the return value of [View class], so if the return value of [View class] does not point to its meta class, who is it ?? who is it point to ??

[View class] 返回与 [View self] 相同的东西:View 类对象。如果要获取对 View 元类对象的引用,则需要直接使用 Objective-C 运行时,如下所示:

NSLog(@"%p", object_getClass([View class]));

请注意,如果您使用 %@ 打印 [View class],它只会打印 View。如果您使用 %@ 打印 object_getClass([View class]),它也只会打印 View。您无法通过字符串描述来区分 View 类对象和 View 元类对象。您必须查看指针值(这确实是您正在做的)。

这是我的测试:

#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;
}

这是输出(删除了 NSLog 绒毛):

v1 = <View: 0x101600780> / 0x101600780
[v1 class] = View / 0x1000011e0
[[v1 class] class] = View / 0x1000011e0
[View class] = View / 0x1000011e0
object_getClass([View class]) = View / 0x1000011b8

所以:

  • 我的 v1 对象位于 0x101600780,
  • View 类对象位于 0x1000011e0,
  • View 元类对象位于 0x1000011b8。

您可能想知道为什么 [View class] 返回View 类对象而不是View 元类对象. Greg Parker 是维护 Objective-C 运行时的主要 Apple 员工,他在 a blog post titled “Classes and metaclasses” 中解释了原因。 :

Objective-C uses metaclasses for practical goals like class methods, but otherwise tends to hide metaclasses. For example, [NSObject class] is identical to [NSObject self], even though in formal terms it ought to return the metaclass that NSObject->isa points to. The Objective-C language is a set of practical compromises; here it limits the class schema before it gets too, well, meta.

关于ios - -(Class)class 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48106850/

相关文章:

ios - SpriteKit `sprite.atlas` 包何时以及如何压缩/优化?

android - 离开页面时如何停止在 initState 中启动的 Timer.periodic

ios - Swift 子类谷歌地图 infoWindow

ios - UIWebview 检测表单文本变化

ios - 在弹出另一个 WatchKit Controller 后立即推送一个新的 WatchKit Controller 总是失败

iphone - iOS 应用程序在生产时崩溃但在调试时不崩溃

ios - 如何将 iOS 设备 token 字符串转换回 NSData

objective-c - NSCollectionView 如何滚动到所选项目

iphone - CGContext 错误/警告

ios - 如何设计自定义 UITableView,如 Google Drive 使用的动画,同时在文件夹结构中向下钻取和向上钻取。