原来在暑假学习iOS开发的时候,因为block中的isa指针,吸引着我慢慢了解到了元类的概念,当时在经历过几天的不断翻博客,终于明白了关于元类的相关东西。
经历过今天的查找,其实在面向对象的语言中,本质上 类也是对象,它也是某个类的实例,这个类我们称之为元类(metaclass)。
在OC中,我们可以通过调用类方法,比如 [NSObject new]
,给类对象发送消息。同样的,类对象能否响应这个消息也要通过 isa
找到类对象所属的类(元类)才能知道。也就是说,实例方法是保存在类中的,而类方法是保存在元类中的。
那元类也是对象吗?是的话那它又是什么类的实例呢?是的,没错,元类也是对象(元类对象),元类也是某个类的实例,这个类我们称之为根元类(root metaclass)。不过,有一点比较特殊,那就是所有的元类所属的类都是同一个根元类(当然根元类也是元类,所以它所属的类也是根元类,即它本身)。根元类指的就是根类的元类,具体来说就是根类 NSObject
对应的元类。
关于Objective-C中元类的相关东西如下(觉得还不错的):
http://www.cocoachina.com/ios/20140715/9142.html
http://blog.leichunfeng.com/blog/2015/04/25/objective-c-object-model/
(英文的)
https://www.devalot.com/articles/2011/11/objc-object-model.html
http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html
而今天引起我又想起来这个是因为,晚上在上Java的课的时候,在听到老师将Java的实例方法。我在下面思考的是不是也是采用相同的方式进行语言的设计的呢?然后在下课回来以后进行了查找,发现在Java、 Python与Objective-C中都有元类的概念。
在OC中,理论上我们可以给元类发送消息,但是 Objective-C 倾向于隐藏元类,不想让大家知道元类的存在。元类是为了保持 Objective-C 对象模型在设计上的完整性而引入的,比如用来保存类方法等,它主要是用来给编译器使用的。而在Java中则不是这样子的,我们可以通过一些方法进行取出相对应的元类。如下:
public class Test {
public static void main(String[] args) {
People xm = new People();
System.out.println(xm.getClass());//xm这个对象为People类的一个对象
System.out.println(xm.getClass().getClass());//People这个对象为Class元类的一个对象
System.out.println(xm.getClass().getClass().getClass());//Class这个对象为Class元类的一个对象
}
}
结果为:
class zj.java.test.People
class java.lang.Class
class java.lang.Class
Java中具体获取对应元类的方式操作见:https://blog.youkuaiyun.com/u012250875/article/details/78087921
在这里面觉得很有用的一段话借鉴一下:获取元类的场景一般是在用到反射时,因为通过元类能拿到类本身的信息,如类的成员变量,构造方法,方法等,这为动态化编程带来了方便,这也是很多框架的基础。