认识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/

时间: 2024-10-09 20:09:59

认识Runtime2的相关文章

腾讯云(Linux)安装.net core sdk2.1、net core runtime2.1

按照微软指令安装: sdk2.1:https://www.microsoft.com/net/download/linux-package-manager/centos/sdk-current 1. sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm 2. sudo yum update 3. sudo yum install dotnet-sdk-2.1 runtime2.

“前.NET Core时代”如何实现跨平台代码重用 ——程序集重用

除了在源代码层面实现共享(“前.NET Core时代”如何实现跨平台代码重用 ——源文件重用)之外,我们还可以跨平台共享同一个程序集,这种独立于具体平台的“中性”程序集通过创建一种名为“可移植类库(PCL: Portable Class Library)”项目来实现.为了让读者朋友们对PCL的实现机制具有充分的认识,我们先来讨论一个被我称为“程序集动态绑定”的话题. 一.何谓程序集动态绑定? 我们采用C#.VB.NET这样的编程语言编写的源文件经过编译会生成有IL代码和元数据构成的托管模块,一个

MapReduce生成HFile文件,再使用BulkLoad导入HBase中(完全分布式运行)

声明: 若要转载, 请标明出处. 前提: 在对于大量的数据导入到HBase中, 如果一条一条进行插入, 则太耗时了, 所以可以先采用MapReduce生成HFile文件, 然后使用BulkLoad导入HBase中. 引用: 一.这种方式有很多的优点: 1. 如果我们一次性入库hbase巨量数据,处理速度慢不说,还特别占用Region资源, 一个比较高效便捷的方法就是使用 "Bulk Loading"方法,即HBase提供的HFileOutputFormat类. 2. 它是利用hbase

.Net AppDomain.CurrentDomain.AppendPrivatePath(@&quot;Libs&quot;);

今天就说说.Net中通过反射取得某个类型时,我们怎么知道这个类型在硬盘上的哪个角落?比如说,假如我们需要要求服务端动态载入某个数据源,那服务端怎么知道数据源在哪? 网上大部分的教程都写着,可以使用Assembly.Load方法来先加载程序集,然后再用Assembly.GetType或者Assembly.GetTypes方法处理. 这个方法很好很实用,基本上也就够了.不过如果这么无聊,也就算不上冷知识,更没有必要写这些了. 如果有办法自动搜索程序集里面有没有暴露对应的类型,我们凭啥还要自行载入程序

程序集重用

程序集重用 除了在源代码层面实现共享(“前.NET Core时代”如何实现跨平台代码重用 ——源文件重用)之外,我们还可以跨平台共享同一个程序集,这种独立于具体平台的“中性”程序集通过创建一种名为“可移植类库(PCL: Portable Class Library)”项目来实现.为了让读者朋友们对PCL的实现机制具有充分的认识,我们先来讨论一个被我称为“程序集动态绑定”的话题. 目录一.何谓程序集动态绑定?二.程序集一致性三.程序集重定向四.类型的转移五.可移植类库(PCL) 一.何谓程序集动态

Android:CheckBox控件

1)ChexkBox继承自CompoundButton组件: 2)isChecked()--确定是否选中:setChecked(bool checked)--设置选中或取消选中: 3)监听事件:CompoundButton.OnCheckedChangeListener 使用checkbox,并实现监听测试: 1)效果: 2)源代码: res\layout\activity_main.xml <RelativeLayout xmlns:android="http://schemas.and

Lua table直接索引VS缓存索引性能测试小示例

local p = {} p.t = {} p.t.p = {} p.t.p.t = {} p.t.p.t.p = {} p.t.p.t.p.t = {} p.t.p.t.p.t.p = {} p.t.p.t.p.t.p.t = {} p.t.p.t.p.t.p.t.p = {} p.t.p.t.p.t.p.t.p.t = {} p.t.p.t.p.t.p.t.p.t.p = {} p.t.p.t.p.t.p.t.p.t.p.t = {} p.t.p.t.p.t.p.t.p.t.p.t.p =

.net core web项目部署centos

前言:最近公司有个项目用 .netcore开发的项目,然后闲的没事就研究如果发布到Linux系统上 需要安装的插件以及支撑架构 1.dotnetSDK 2.jexus Jexus 是Linux平台上 的一款免费的ASP.NET WEB服务器.它是 Linux.Unix.FreeBSD等非Windows系统架设 ASP.NET WEB 服务器的核心程序,具备反向代理.入侵检测等重要功能.拥有IIS和其它Web服务器所不具备的高度的安全性 3.supervisord supervisord 是用Py

Goroutine并发调度模型深度解析之手撸一个协程池

golanggoroutine协程池Groutine Pool高并发 并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题:Go语言作为一个出道以来就自带 『高并发』光环的富二代编程语言,它的并发(并行)编程肯定是值得开发者去探究的,而Go语言中的并发(并行)编程是经由goroutine实现的,goroutine是golang最重要的特性之一,具有使用成本低.消耗资源低.能效高等特点,官方宣称原生goroutine并发成千上万不成问题,于是它也成为Gopher们经常