认识Runtime2

简介:

我定义了一个Person类作为测试。

其中Person.h:

复制代码
//
//  Person.h
//  Test
//
//  Created by zhanggui on 15/8/16.
//  Copyright (c) 2015年 zhanggui. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UITabBar.h>
@protocol PersonDelete <NSObject>

- (void)protocolMethod1;
- (void)protocolMethod2;

@end
@interface Person : NSObject<UITabBarDelegate>

@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSUInteger age;
@property (nonatomic,copy)NSString *address;
- (void)personRun;
- (void)eat;
- (void)goToSchool:(NSString *)vehicle;

+ (void)method1;
@end
复制代码

Person.m:

复制代码
//
//  Person.m
//  Test
//
//  Created by zhanggui on 15/8/16.
//  Copyright (c) 2015年 zhanggui. All rights reserved.
//

#import "Person.h"


@implementation Person

- (void)personRun {
    NSLog(@"run method was called");
}
- (void)eat {
    NSLog(@"eat method was called");
}
- (void)goToSchool:(NSString *)vehicle {
    NSLog(@"Person go to school by %@",vehicle);
}
+ (void)method1 {
    NSLog(@"类方法");
}
@end
复制代码

然后集中在ViewController中的viewDieLoad方法中测试:(具体的讲解都在注释中了)

复制代码
- (void)viewDidLoad {
    [super viewDidLoad];
    Person *person = [[Person alloc] init];
    unsigned int outCount = 0;
    Class cls = person.class;   //得到Person的class
    //--------------------类名
    NSLog(@"类名是 :%s",class_getName(cls));
    //-----------父类
    NSLog(@"父类名是:%s",class_getName(class_getSuperclass(cls)));
    
    //是否是元类
    if (class_isMetaClass(cls)) {
        NSLog(@"Person是元类");
    }else
    {
        NSLog(@"Person不是元类");
    }
    //返回指定类的元类
    Class meta_class = objc_getMetaClass(class_getName(cls));
    NSLog(@"%ss 的元类 是 %s",class_getName(cls),class_getName(meta_class));
    
    //变量实例大小  %zu用来输出size_t类型的。
    NSLog(@"实例大小::%zu",class_getInstanceSize(cls));
    
    //成员变量 Iavr:一个不透明的类型代表实例变量。这里可以得到其所有的成员变量
    Ivar *ivars = class_copyIvarList(cls, &outCount);
    for (int i=0;i<outCount;i++)
    {
        Ivar ivar = ivars[i];
        NSLog(@"实例变量的名字:%s at index %d",ivar_getName(ivar),i);
    }
    free(ivars);    //释放成员变量实例
    //通过名字:获取指定的实例变量,,比如我想获取该类是否有_name这个变量就可以通过该方法获得。
    Ivar string = class_getInstanceVariable(cls, "_name");
    if (string!=NULL) {
        NSLog(@"%s有实列变量:%s",class_getName(cls),ivar_getName(string));
    }else
    {
         NSLog(@"%s没有指定的实列变量:%s",class_getName(cls),ivar_getName(string));
    }
    
    
    //属性操作:objc_porperty:代表公开的属性.class_getProperty的参数中:cls代表该类的class,name是该类的属性
    objc_property_t array = class_getProperty(cls, "name");
    if (array!=NULL) {
        NSLog(@"属性:%s",property_getName(array));
    }
    //方法操作:
    Method *methods = class_copyMethodList(cls, &outCount);
    for (int i=0; i<outCount; i++) {
        Method method = methods[i];
        NSLog(@"方法签名是:%s",sel_getName(method_getName(method)));   //sel_getName:得到方法名字
    }
    free(methods);   //释放methods所占用的内存
//    typedef struct objc_method *Method;
    //这里得到的是类方法
//    struct objc_method {
//        SEL method_name                                          OBJC2_UNAVAILABLE;
//        char *method_types                                       OBJC2_UNAVAILABLE;
//        IMP method_imp                                           OBJC2_UNAVAILABLE;
//    }
//IMP

    Method classMethod = class_getClassMethod(cls, @selector(method1));
    if (classMethod!=NULL) {
        NSLog(@"%s 有该类方法:%s",class_getName(cls),sel_getName(method_getName(classMethod)));
    }else
    {
        NSLog(@"%s 没有该类方法:%s",class_getName(cls),sel_getName(method_getName(classMethod)));
    }
    
    //判断类的实例是否相应某个方法:比如alloc就不响应,而init就相应
    if (class_respondsToSelector(cls, @selector(alloc))) {
        NSLog(@"Person实例 响应 alloc");
    }else
    {
         NSLog(@"Person实例 不响应 alloc");
    }
    //函数指针
    IMP imp = class_getMethodImplementation(cls, @selector(eat));
    imp();
    //获得该类具有的协议
    Protocol *__unsafe_unretained * protocols = class_copyProtocolList(cls, &outCount);
    Protocol *protocol;
    for (int i=0; i<outCount; i++) {
        protocol = protocols[i];
        NSLog(@"协议名称:%s",protocol_getName(protocol));
    }
    //判断是否遵守协议
    if (class_conformsToProtocol(cls, protocol)) {
        NSLog(@"Person遵守协议%s",protocol_getName(protocol));
    }else
    {
         NSLog(@"Person不遵守协议%s",protocol_getName(protocol));
    }
    
}
复制代码

附:

参考与:http://southpeak.github.io/blog/2014/10/25/objective-c-runtime-yun-xing-shi-zhi-lei-yu-dui-xiang/

相关文章
|
29天前
|
Linux Shell Windows
Java.Runtime.exec()的使用
Java.Runtime.exec()的使用
10 0
|
Kubernetes API 调度
Container Runtime CDI与NRI介绍
CDI介绍什么是CDICDI(Container Device Interface)是Container Runtimes支持挂载第三方设备(比如:GPU、FPGA等)机制。它引入了设备作为资源的抽象概念,这类设备由一个完全限定的名称唯一指定,该名称由设备商ID,设备类别与一个设备类别下的一个唯一名称组成,格式如下:vendor.com/class=unique_name设备商ID和设备类型(ve
2990 1
Container Runtime CDI与NRI介绍
|
存储 编译器 API
Runtime的使用
Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的。
228 0
Runtime的使用
|
编译器 C语言 iOS开发
Runtime详解及应用
动态语言:编译时确定变量的数据类型。 静态语言:运行时确定变得的数据类型。
267 0
Runtime详解及应用
|
设计模式 Java 开发者
Runtime 相关说明 | 学习笔记
快速学习 Runtime 相关说明。
114 0
|
设计模式 Java 开发者
Runtime 类|学习笔记
快速学习 Runtime 类
Runtime 类|学习笔记
|
C++
C++ runtime sample
本文演示如何利用函数计算的自定义Runtime功能来运行C++代码
1737 0
|
缓存 iOS开发 编译器
Runtime那些事
Runtime介绍。
2004 0
|
Windows 设计模式

热门文章

最新文章