oc中Class是个啥

2024-06-16 20:38
文章标签 oc class

本文主要是介绍oc中Class是个啥,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1. 先来看看熟悉的NSObject是个啥吧

     @interface NSObject <NSObject> {Class isa  OBJC_ISA_AVAILABILITY;}
  2. Class是个啥
    typedef struct objc_class *Class;

  3. objc_class是什么呢

struct objc_class {Class isa  OBJC_ISA_AVAILABILITY;#if !__OBJC2__Class super_class                                        OBJC2_UNAVAILABLE;const char *name                                         OBJC2_UNAVAILABLE;long version                                             OBJC2_UNAVAILABLE;long info                                                OBJC2_UNAVAILABLE;long instance_size                                       OBJC2_UNAVAILABLE;struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;struct objc_cache *cache                                 OBJC2_UNAVAILABLE;struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif} OBJC2_UNAVAILABLE;

宏判断之间的字段就不一一解释了,网上一搜一大堆。
从这里我们知道,Class是一个结构体,里面保存了类相关的信息。objc_class中本身也有一个Class的字段,即meta-class,指向的还是一个class。于是,网上的有了这样一张图:


Class&MetaClass.001.jpg

简单的说:
当我们发送一个消息给一个NSObject对象时,这条消息会在对象的类的方法列表里查找
当我们发送一个消息给一个类时,这条消息会在类的Meta Class的方法列表里查找

好,以上在网上均可以查到更加详细的资料。下面我们来做道题。

BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];

这道题本意应该是考察对Class、MetaClass的理解,其实我觉着他更像是考isKindOfClass、isMemberOfClass的实现,挖了好大一个坑的说。

先看一下class的实现吧:

+ (Class)class {return self;
}

即返回NSObject。

现在我们分析一下res1。看上去应该是这样的:NSObject isKindOfClass NSObject,显然res1 = YES。
(这有何难!!!)
如果你是这样理解的,那么恭喜你,掉坑里了。。。。
我们再看下isKindOfClass的实现

+ (BOOL)isKindOfClass:(Class)cls {for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {if (tcls == cls) return YES;}return NO;
}

和object_getClass的实现

Class object_getClass(id obj)
{if (obj) return obj->getIsa();else return Nil;
}

isKindOfClass先获取receiver的isa,然后再与参数进行比较。
正确的思考应该是这样的:
1.取得NSObject的isa,既meta_NSObject(我自己瞎编的名字),这个时候meta_NSObject != NSObject
2.根据源码,接下来取meta_NSObject的superClass,根据上一期的类图,即NSObject,这下NSObject == NSObject了。
3.return YES;

剩下的res2、res3同理分析一下~~~~
均为NO。
附录:

+ (BOOL)isMemberOfClass:(Class)cls {return object_getClass((id)self) == cls;
}

这篇关于oc中Class是个啥的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067496

相关文章

OC 中的*前const与*后const

int const *p2; int *const p3; 这个什么不能改由const后面的内容决定,如果是*p的话,则*p不可以改。 也就是说p指向的内容不能改变 如果const后面是p的话,则p不能改,也就是说p的指向不可以改变 OC中的字符串的话 NSString* name=@"wangning"; 此时我们不想让外界改变name的值得话const应该加在 NS

OC和 C语言中的const

const与宏对比 1.都是在其他的地方不可以改变 2.一个地方改了其他的地方都会改变。 而且宏定义的缺陷是, 是它会不断的开辟临时变量的存储空间 使用const的话 是都去使用同一的一份空间,使用同一个对象。 加const 之后变量还是全局的,只不过变为全局常量。 如果此时改变量不想被被类外面访问的话,可以加上static关键字, 3.下次想要定义一些宏的时候分

OC 中的深拷贝和浅拷贝

1.指针地址拷贝,浅拷贝,拷贝的只是指针地址,一旦我通过这个地址修改了值,那么原来的内存保存的值也会变化 2.mutablecopy  深拷贝,产生新对象 copy与mutablecopy区别在于返回的值,copy返回不可变对象,mutableCopy返回可以变化的值

OC中的static关键字

1.修饰局部变量      1.只会初始化一次      2.全局只会存在一份内存      3.不会改变自身的作用域,比如原来是局部变量现在的话依然是局部变量      4.生命周期延长(直到程序结束,这个局部变量才会被销毁)      2.  修饰全局变量     static 修饰的全局变量 在整个工程 中只会存在一份     只可以在当前的.h .m文件中才可以访问。 如果单纯全局变量的

Class 对象在执行引擎中的初始化过程

一个 class 文件被加载到内存中需要经过 3 大步:装载、链接、初始化。 装载 装载是指 Java 虚拟机查找 .class 文件并生成字节流,然后根据字节流创建 java.lang.Class 对象的过程。 链接 链接过程分为 3 步:验证、准备、解析。 验证: 初始化 这是 class 加载的最后一步,这一阶段是执行类构造器方法的过程,并真正初始化类变量。 1.文件格式检验:检

在eclipse中进行nutch1.7二次开发通过ant编译build.xml出现Class not found javac1.8

把nutch1.7通过svn导入到本地后打算进行二次开发却在开始用ant进行build.xml构建的时候出现Class not found javac1.8 暂且不管哪个sonar没有找到的问题,我们先把那个Class not found :javac1.8的问题: 多半是因为Ant版本太低,低于1.9,无法和java1.8兼容,因为我的java运行环境是1.8的,Ant版本也是1.8,所

iOS OC底层面试题(KVO (Key-value observing))

KVO (Key-value observing) KVO是观察者模式的另一实现。 使用了isa混写(isa-swizzling)来实现KVO 使用setter方法改变值KVO会生效,使用setValue:forKey即KVC改变值KVO也会生效,因为KVC会去调用setter方法 - (void)setValue:(id)value{[self willChangeValueForKey

iOS OC底层面试题(KVC(Key-value coding)

KVC(Key-value coding) -(id)valueForKey:(NSString *)key;-(void)setValue:(id)value forKey:(NSString *)key; KVC就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。而不是在编译时

Java项目中Class:xxx

文件定位的时候我们经常使用: classpath:xxx. 这个classpath.会自动查找resources文件夹下(不是名字叫resources,而是指文件类型),以及WEB-INF下是否有与XXX匹配的文件。 classpath:/xxx 和 classpath:xxx是一样的 classpath:xxx 和 classpath*:xxx是不一样的,前者表示引入第一个,后者表示引入

JVM中class对象加载方式

文章目录 1 class对象详解2 Class.forName和ClassLoader.loadClass区别2.1 jvm加载class步骤2.2 两种方式的详细方法2.3 两种方式的区别2.4 举例说明他们各自的使用方法 1 class对象详解 java中把生成Class对象和实例对象弄混了,更何况生成Class对象和生成instance都有多种方式。所以只有弄清其中的原