[runtime] MAObjCRuntime

MAObjCRuntime

 

源码地址:(引入头文件MARTNSObject.h即可,非arc环境下)

http://pan.baidu.com/s/1eQ6776U

https://github.com/mikeash/MAObjCRuntime

MAObjCRuntime is an ObjC wrapper around the Objective-C runtime APIs. If that's confusing, it provides a nice object-oriented interface around (some of) the C functions in /usr/include/objc.

MAObjCRuntime 是对 Objective-C runtime 的 API 的封装。如果你觉得 runtime 的 API 让你迷惑。那这个 MAObjCRuntime 就给你提供了一个对象导向型的接口方便你使用。

Quick Start(快速开始)

The action begins in MARTNSObject.h. Various methods are added to NSObject to allow querying and manipulation. Most of these are class methods, because they operate on classes. There are a couple of instance methods as well. All of these methods start with rt_ to avoid name conflicts. The RTMethod and RTIvar classes are used to represent a single method and a single instance variable, respectively. Their use should be fairly obvious.

你可以在 MARTNSObject.h 文件开始着手。里面提供了很多不同的方法,用来给 NSObject 添加了许多方法,允许你来进行相关查询和操作。绝大部分都为类方法,因为他们都是来操作类的。也有着许多实例方法。所有的方法都以 rt_ 开头,为了避免名字的冲突。

这个 RTMethod 和 RTIvar 分别代表一个方法以及一个实例变量,你看看就知道怎么用了。

Querying(查询)

You can query any class's methods, instance variables, or other attributes using the methods provided. For example:

你可以查询所有类的方法,实例变量,或者属性,例如:

// get all subclasses of a class
NSArray *subclasses = [MyClass rt_subclasses];

// check out the methods on NSString
NSArray *methods = [NSString rt_methods];
for(RTMethod *method in methods)
    NSLog(@"%@", method);

// does it have any ivars?
NSLog(@"%@", [NSString rt_ivars]);

// how big is a constant string instance?
NSLog(@"%ld", (long)[[@"foo" rt_class] rt_instanceSize]);

Modifying(修改)

You can add new methods using +rt_addMethod:. You can modify the implementation of an existing method using the -setImplementation: method on RTMethod. Example:

你可以使用 +rt_addMethod: 添加新的方法。你可以使用 -setImplementation:来修改方法,例如:

// swizzle out -[NSObject description] (don't do this)
static NSString *NewDescription(id self, SEL _cmd)
{
    return @"HELLO WORLD!";
}

Method *description = [NSObject rt_methodForSelector: @selector(description)];
[description setImplementation: (IMP)NewDescription];

You can create new classes using +rt_createSubclassNamed: or +rt_createUnregisteredSubclassNamed:. Note that if you want to add instance variables to a class then you have to use the Unregistered version, and add them before registering the class.

你可以使用 +rt_createSubclassNamed: 或者 +rt_createUnregisteredSubclassNamed: 创建新的类。注意,如果你想添加实例变量到一个类中,你必须使用未登记的版本,在注册这个类之前添加上他们。

Objects(对象)

Two instance methods are provided as well. -rt_class exists because Apple likes to fiddle with the return value of -class, and -rt_class always gives you the right value. -rt_setClass: does pretty much what it says: sets the class of the object. It won't reallocate the object or anything, so the new class had better have a memory layout that's compatible with the old one, or else hilarity will ensue.

提供了两个实例方法。之所以存在 -rt_class 是因为苹果喜欢瞎折腾 -class 的返回值,所以,-rt_class 能时常给你正确的值。-rt_setClass: 已经够见名知意了。设置这个对象的类。它不会再给这个对象分配更多的空间,所以,新类最好有一个好的内存布局且能兼容设置之前的类,否则会让你癫狂的。

Sending Messages(发送消息)

After getting a list of methods from a class, it's common to want to actually use those on instances of the class.RTMethod provides an easy method for doing this, as well as several convenience wrappers around it.

当你从一个类中得到了一个方法的列表。你肯定就想在这个类的实例对象上试一下效果。RTMethod 提供了一个简单的方法来帮你干这种事情,同时也有一些其它便利的封装来实现这个功能。

The basic method for sending messages is -[RTMethod returnValue:sendToTarget:]. You use it like this:

最基础的用来发送消息的方法是 -[RTMethod returnValue:sendToTarget:],你可以这样子用:

RTMethod *method = ...;
SomeType ret;
[method returnValue: &ret sendToTarget: obj, RTARG(@"hello"), RTARG(42), RTARG(xyz)];

It may seem odd to have the return value at the beginning of the argument list, but this comes closest to the order of the normal ret = [obj method] syntax.

返回值放在第一个位置看起来很奇怪,但是呢,他是最接近普通的 ret = [obj method] 的语法规则了。

All arguments must be wrapped in the RTARG macro. This macro takes care of packaging up each argument so that it can survive passage through the variable argument list and also includes some extra metadata about the argument types so that the code can do some basic sanity checking. No automatic type conversions are performed. If you pass a double to a method that expects an int, this method will abort. That checking is only based on size, however, so if you pass a float where an int is expected, you'll just get a bad value.

所有的参数都必须在 RTARG 宏中封装起来。这个宏用来处理每一个参数,这样才能确保消息在通过不同的变量列表时,有时还包括了一些额外附加的元数据进行基本的检测。没有自动便利的类型转换。如果你传递了个double,而那个方法期望得到int,这个方法就会崩溃。那个仅仅是用来检测基本的类型的size的。然而,如果你传进了一个float参数,但是int是它期望得到的值,你将会得到一个错误的返回值,但不会崩溃。

Note that while it's not 100% guaranteed, this code does a generally good job of detecting if you forgot to use theRTARG macro and warning you loudly and calling abort instead of simply crashing in a mysterious manner. Also note that there is no sanity checking on the return value, so it's your responsibility to ensure that you use the right type and have enough space to hold it.

注意,这个是不能100%确保的,这份代码已经做到了很好的处理了,如果你忘记使用这个宏 RTARG ,那么就会很明显的警告你并直接导致崩溃,而不是简单的不知道啥原因的崩溃。注意,这个并没有检测返回值,如何正确的处理返回值,腾出足够的空间来接收返回值就是你的事情了。

For methods which return an object, the -[RTMethod sendToTarget:] method is provided which directly returns id instead of making you use return-by-reference. This simplifies the calling of such methods:

对于返回一个对象的方法,你可以使用这个 -[RTMethod sendToTarget:] 来直接得到返回的 id ,多方便。

RTMethod *method = ...;
id ret = [method sendToTarget: obj, RTARG(@"hello"), RTARG(42), RTARG(xyz)];

There is also an NSObject category which provides methods that allows you to switch the order around to be more natural. For example:

也有 NSObject 的类目文件,它提供的方法允许你调整顺序让其更加自然,例如:

RTMethod *method = ...;
id ret = [obj rt_sendMethod: method, RTARG(@"hello"), RTARG(42), RTARG(xyz)];

And the same idea for rt_returnValue:sendMethod:.

这个方法 rt_returnValue:sendMethod:也有这功能:

Finally, there are a pair of convenience methods that take a selector, and combine the method lookup with the actual message sending:

最后,有一对便利的方法来获取一个selector,来组合这个方法,看起来更加自然的发送一条消息^_^:

id ret = [obj rt_sendSelector: @selector(...), RTARG(@"hello"), RTARG(42), RTARG(xyz)];
SomeType ret2;
[obj rt_returnValue: &ret2 sendSelector: @selector(...), RTARG(12345)];

 

 

时间: 2024-09-20 12:06:16

[runtime] MAObjCRuntime的相关文章

iOS开发之遍历Model类的属性并完善使用Runtime给Model类赋值

在上篇博客<iOS开发之使用Runtime给Model类赋值>中介绍了如何使用运行时在实体类的基类中添加给实体类的属性赋值的方法,这个方法的前提是字典的Key必须和实体类的Property Name相同,然后通过运行时来生成和执行Setter方法给Model类的属性赋值. 通过Runtime来给Model类属性赋值的好处是多多的,它便于代码的后期维护,并且提高了开发效率.当你拿到解析后的字典时你不用一个一个的通过key去把字典的值赋值给相应的Model类的属性,本篇博客中会给出如何去遍历Mod

ASP.NET错误处理:Runtime Error

服务器上出现应用程序错误.此应用程序的当前自定义错误设置禁止查看应用程序错误的详细信息. Runtime Error 运行时错误 Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely

通过runtime获取对象相关信息

通过runtime获取对象相关信息 在这里,本人给大家提供一个runtime关于NSObject的扩展,用来显示各种NSObject中的信息,这有助于你来分析类的组成:) 先准备以下类供测试: Model.h 与 Model.m // // Model.h // Runtime // // Copyright (c) 2014年 Y.X. All rights reserved. // #import <Foundation/Foundation.h> typedef enum : NSUIn

关于在oj上出现Runtime error 的情况

 越栈了,比如数组开的不够大 编译错误时Compilation Error Runtime Error (RE) : 运行时错误,这个一般是程序在运行期间执行了非法的操作造成的.以下列出常见的错误类型: ACCESS_VIOLATION 您的程序想从一些非法的地址空间读取或向其中写入内容.一般例如指针.数组下标越界都会造成这个错误的. ARRAY_BOUNDS_EXCEEDED 您的程序试图访问一个超出硬件支持范围的数组单元. FLOAT_DENORMAL_OPERAND 进行了一个非正常的

启动红蜻蜓抓图精灵时跳出Run-time error &amp;#039;339&amp;#039;错误消息框

  有用户反映在打开红蜻蜓抓图精灵时,会弹出一个对话框,提示"Run-time error '339': Component 'Flash11e.ocx' or one of its dependencies not correctly registered: a file is missing or invalid".出现此问题,是由于用户电脑上Flash播放控件缺失所引起,下载安装最新版的Flash播放控件即可解决问题.Flash播放控件的官方下载地址:http://www.ado

Overloading overriding runtime type and object orientation (1)

loading|object 6)Overloading overriding runtime type and object orientationObjective 1)State the benefits of encapsulation in object oriented design and write code that implements tightly encapsulated classes and the relationships "is a" and &qu

&amp;gt; 第二章 NGWS Runtime 技术基础(rainbow 翻译) (转自重粒子空

<<展现C#>> 第二章 NGWS Runtime 技术基础(rainbow 翻译)   出处:http://www.informit.com/matter/ser0000001/chapter1/ch02.shtml 正文: 第二章  NGWS  runtime 技术基础     既然你已经具有了C#全面的印象,我也想让你了解NGWS runtime的全貌.C#依靠由NGWS提供的运行时:因此,有必要知道运行时如何工作,以及它背后所蕴含的概念.    所以,这一章分为两部分--它

C++:RTTI(RunTime Type Information)运行时类型信息 详解

RTTI, RunTime Type Information, 运行时类型信息, 是多态的主要组成部分, 通过运行时(runtime)确定使用的类型, 执行不同的函数,复用(reuse)接口. dynamic_cast<>可以 使基类指针转换为派生类的指针, 通过判断指针的类型, 可以决定使用的函数. typeid(), 可以判断类型信息, 判断指针指向位置, 在多态中, 可以判断基类还是派生类. 代码: /* * test.cpp * * Created on: 2014.04.22 * A

树上三角形解决RE Runtime Error

时间限制:4000ms 单点时限:2000ms 内存限制:256MB 描述 有一棵树,树上有只毛毛虫.它在这棵树上生活了很久,对它的构造了如指掌.所以它在树上从来都是走最短路,不会绕路.它还还特别喜欢三角形,所以当它在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢? 输入 输入数据的第一行包含一个整数 T,表示数据组数. 接下来有 T 组数据,每组数据中: 第一行包含一个整数 N,表示树上节点的个数(从 1到 N标号). 接下来的 N-1