路漫漫其修远兮,吾将上下而求索!

Objective-C语言的许多决策可以在编译和运行时执行。只要有可能,它是动态的。这意味着Objective-C语言不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。Runtime系统是一种用于Objective-C语言的操作系统,它使OC语言工作起来。   Runtime的核心是在运行时动态操作类和消息分发给其他对象,本文档主要介绍在运行时动态操作类。   你可以从中学到运行时动态操作类。但是,多数情况下,我们并不需要编写Runtime系统的相关代码。   

注意:在Runtime中,所有的char * 数据是UTF-8编码。

一、准备工作1. 导入框架objc/runtime.h#import < objc/runtime.h >2. User类

User.h

#import <Foundation/Foundation.h>/// 用户@interface User : NSObject@property (nonatomic, copy) NSString *userName;///< 用户名/** * 初始化 * * @param userName 用户名 * * @return id */- (id)initWithUserName:(NSString *)userName;/** * 初始化 * * @param userName 用户名 * * @return id */+ (id)userWithUserName:(NSString *)userName;@end

User.m

@implementation User+ (id)userWithUserName:(NSString *)userName{User *user = [[User alloc] init];user.userName = userName;return userName;}#pragma mark 初始化- (id)initWithUserName:(NSString *)userName{self = [super init];if (self) {self.userName = userName;}return self;}@end

二、类

1.源代码

#pragma mark – 类- (void)testClass{// 获取类id userClass = objc_getClass(“User”);NSLog(@”%@”, userClass);// 等价userClass = [User class];NSLog(@”%@”, userClass);// 父类fprintf(stdout, “\n父类\n”);id superUserClass = class_getSuperclass(userClass);NSLog(@”%@”, superUserClass);// 等价superUserClass = [User new].superclass;NSLog(@”%@”, superUserClass);// 更改对象的类fprintf(stdout, “\n更改对象的类\n”);User *user = [User new];NSLog(@”类:%@ userName:%@”, user, user.userName);userClass = object_setClass(user, [ClassTest class]);// 类替换,,并返回原来的类属性NSLog(@”类:%@ userName:%@”, user, user.userName);}

2.输出 2015-09-23 10:12:52.140 Runtime[14129:681188] User 2015-09-23 10:12:52.141 Runtime[14129:681188] User

父类 2015-09-23 10:12:52.141 Runtime[14129:681188] NSObject 2015-09-23 10:12:52.141 Runtime[14129:681188] NSObject

更改对象的类 2015-09-23 10:12:52.141 Runtime[14129:681188] 类: userName:(null) 2015-09-23 10:12:52.141 Runtime[14129:681188] 类: userName:阳君

三、类名

1.源代码

#pragma mark – 类名- (void)testName{// 获取classid userClass = objc_getClass(“User”);const char *className = class_getName(userClass);fprintf(stdout, “类名:%s\n”, className);// 等价className = object_getClassName(userClass);fprintf(stdout, “类名:%s\n”, className);// 等价OCuserClass = [User class];NSString *name = NSStringFromClass(userClass);NSLog(@”类名:%@”, name);// 底层转换name = [NSString stringWithCString:className encoding:NSUTF8StringEncoding];NSLog(@”类名:%@”, name);}

2.输出 类名:User 类名:User 2015-09-23 10:14:03.278 Runtime[14140:681770] 类名:User 2015-09-23 10:14:03.279 Runtime[14140:681770] 类名:User

四、属性

1.源代码

#pragma mark – 属性- (void)testPropertyName{// 获取所有属性fprintf(stdout, “获取所有属性\n”);id userClass = objc_getClass(“User”);unsigned int outCount, i;objc_property_t *properties = class_copyPropertyList(userClass, &outCount);// 所有属性for (i = 0; i < outCount; i++) {objc_property_t property = properties[i];*propertyName = property_getName(property);*propertyAttributes = property_getAttributes(property); //属性类型fprintf(stdout, “%s %s\n”, propertyName, propertyAttributes);// 等价输出NSLog(@”%@”, [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]);}// 单一属性fprintf(stdout, “\n单一属性\n”);Ivar var = class_getInstanceVariable(userClass, “_userName”);const char *typeEncoding =ivar_getTypeEncoding(var);const char *ivarName = ivar_getName(var);fprintf(stdout, “属性名:%s; 类型:%s\n”, ivarName, typeEncoding);// 设置/获取属性值,需要关闭ARC模式fprintf(stdout, “\n设置/获取属性值\n”);User *user = [[[User alloc] init] autorelease];NSString *userName = @”阳君”;object_setInstanceVariable(user, “_userName”, userName);NSLog(@”user.userName:%@”, user.userName);user.userName = @”开启ARC”;// 修改值object_getInstanceVariable(user, “_userName”, (void*)&userName);NSLog(@”user.userName:%@”, userName);}

2.输出 获取所有属性 userName T@”NSString”,C,N,V_userName 2015-09-23 10:18:54.365 Runtime[14155:684097] userName

单一属性 属性名:_userName; 类型:@”NSString”

设置/获取属性值 2015-09-23 10:18:54.366 Runtime[14155:684097] user.userName:阳君 2015-09-23 10:18:54.367 Runtime[14155:684097] user.userName:开启ARC

五、方法却还是,会愚蠢的选择相互敌视的方式。即使背脊相抵,

路漫漫其修远兮,吾将上下而求索!

相关文章:

你感兴趣的文章:

标签云: