CCRuntime
(CCRuntime 转换 MAObjCRuntime 以支持 ARC)
CCRuntime是围绕Objective-C运行时API的ObjC封装器。如果这令您困惑,它提供了一种围绕(一些)/usr/include/objc中的C函数的优美面向对象的接口。
CCRuntime在BSD许可下发布。有关官方许可证,请参阅LICENSE文件。
多语言翻译
快速入门
操作从CCRuntime.h
开始。向NSObject
添加了各种方法以允许查询和操作。其中大部分是类方法,因为它们操作类。还有一些实例方法。所有这些方法都以前缀cc_
开始,以避免名称冲突。《CCMethod》和《CCIvar》类用于表示单个方法和单个实例变量。它们的使用应该非常明显。
查询
您可以使用提供的方法查询任何类的函数、实例变量或其他属性。例如
// get all subclasses of a class
NSArray *subclasses = [MyClass cc_subclasses];
// check out the methods on NSString
NSArray *methods = [NSString cc_methods];
for(CCMethod *method in methods)
NSLog(@"%@", method);
// does it have any ivars?
NSLog(@"%@", [NSString cc_ivars]);
// how big is a constant string instance?
NSLog(@"%ld", (long)[[@"foo" cc_class] cc_instanceSize]);
修改
您可以使用+cc_addMethod
添加新方法。您可以通过CCMethod
上的-setImplementation:
方法来修改现有方法的实现。示例
// swizzle out -[NSObject description] (don't do this)
static NSString *NewDescription(id self, SEL _cmd)
{
return @"HELLO WORLD!";
}
CCMethod *description = [NSObject cc_methodForSelector: @selector(description)];
[description setImplementation: (IMP)NewDescription];
您可以使用+cc_createSubclassNamed:
或+cc_createUnregisteredSubclassNamed:
创建新类。注意,如果您想向类中添加实例变量,则必须使用未注册版本,并在注册类之前添加它们。
对象
还提供了两个实例方法。因为Apple喜欢篡改-class
的返回值,所以存在-cc_class
,并且-cc_class
始终给出正确的值。-cc_setClass:
基本上做它所说的事情:设置对象的类。它不会重新分配对象或任何东西,因此新类必须与旧类兼容的内存布局,或者将会出现荒谬的情况。
发送消息
在从一个类获取方法列表之后,通常想要实际在类的实例上使用这些方法。CCMethod
提供了一个简单的方法来完成这项工作,以及围绕它的几个便利包装器。
发送消息的基本方法是-[CCMethod returnValue:sendToTarget:]
。您可以使用它像这样
CCMethod *method = ...;
SomeType ret;
[method returnValue: &ret sendToTarget: obj, CCARG(@"hello"), CCARG(42), CCARG(xyz)];
将返回值放在参数列表的开头似乎有点奇怪,但这与普通的ret = [obj method]
语法顺序最接近。
所有参数都必须包装在CCARG
宏中。此宏负责包装每个参数,使其能够穿过变量参数列表,并包含有关参数类型的额外元数据,以便代码可以执行一些基本的有效性检查。不执行自动类型转换。如果您向期望abort
。但是,检查只能基于大小,因此如果您在期望
请注意,虽然不能保证100%,但此代码通常会很好地检测您是否忘记使用CCARG
宏,并大声警告您并调用abort
而不是以神秘的方式崩溃。此外,请注意,没有对返回值进行有效性检查,因此您负责确保使用正确的类型并且有足够的空间来存储它。
对于返回对象的函数,提供了-[CCMethod sendToTarget:]
方法,它直接返回id
,而不是让你使用引用返回。这简化了这类方法的调用。
CCMethod *method = ...;
id ret = [method sendToTarget: obj, CCARG(@"hello"), CCARG(42), CCARG(xyz)];
还有一个NSObject
类别,它提供的方法允许你切换顺序以使其更自然。例如:
CCMethod *method = ...;
id ret = [obj cc_sendMethod: method, CCARG(@"hello"), CCARG(42), CCARG(xyz)];
对于cc_returnValue:sendMethod:
,采用同样的思路。
最后,有一对方便的方法,它们接受选择器,并将方法查找与实际的消息发送结合起来。
id ret = [obj cc_sendSelector: @selector(...), CCARG(@"hello"), CCARG(42), CCARG(xyz)];
SomeType ret2;
[obj cc_returnValue: &ret2 sendSelector: @selector(...), CCARG(12345)];
BSD
BSD 3-Clause License
版权所有 (c) 2018至今 ccworld1000 | 错误报告:[email protected]
保留所有权利。
在不违反以下条件的情况下,允许以源代码和二进制形式重新分发和使用,无论是否修改
-
源代码的分发必须保留上述版权声明、本许可列表和以下免责声明。
-
二进制形式的分发必须复制上述版权声明、本许可列表和以下免责声明在提供的文档和其他材料中。
-
未经事先书面许可,不得使用版权持有者或其贡献者的姓名支持或推广源自本软件的产品。
本软件由版权持有者和贡献者提供“按原样”和任何明确或隐含的保证,包括但不限于默示的适销性和针对特定目的的适用性保证。在任何情况下,无论由于使用或 otherwise 软件使用,无论告知可能发生的损害,版权持有者或贡献者均不对任何直接、间接、偶然、特殊、示范性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;业务中断)承担责任,即使事先告知可能发生的损害也是如此。