当前位置: 移动技术网 > IT编程>开发语言>C/C++ > Objective-C Runtime Classes

Objective-C Runtime Classes

2018年11月01日  | 移动技术网IT编程  | 我要评论

澳门赌场haobc,卢子跃简历,e-mail申请

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

//
//  user.h
//  runtime
//
//  created by yangjun on 15/9/21.
//  copyright © 2015年 六月. all rights reserved.
//

#import 

/// 用户
@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

//
//  user.m
//  runtime
//
//  created by yangjun on 15/9/21.
//  copyright © 2015年 六月. all rights reserved.
//

#import user.h

@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, 
父类
);
    id superuserclass = class_getsuperclass(userclass);
    nslog(@%@, superuserclass);
    // 等价
    superuserclass = [user new].superclass;
    nslog(@%@, superuserclass);

    // 更改对象的类
    fprintf(stdout, 
更改对象的类
);
    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{
    // 获取class
    id userclass = objc_getclass(user);
    const char *classname = class_getname(userclass);
    fprintf(stdout, 类名:%s
, classname);
    // 等价
    classname = object_getclassname(userclass);
    fprintf(stdout, 类名:%s
, classname);
    // 等价oc
    userclass = [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, 获取所有属性
);
    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];// 属性
        const char *propertyname = property_getname(property);// 属性名
        const char *propertyattributes = property_getattributes(property); //属性类型
        fprintf(stdout, %s %s
, propertyname, propertyattributes);
        // 等价输出
        nslog(@%@, [nsstring stringwithcstring:propertyname encoding:nsutf8stringencoding]);
    }

    // 单一属性
    fprintf(stdout, 
单一属性
);
    ivar var = class_getinstancevariable(userclass, _username);
    const char *typeencoding =ivar_gettypeencoding(var);
    const char *ivarname = ivar_getname(var);
    fprintf(stdout, 属性名:%s; 类型:%s
, ivarname, typeencoding);

    // 设置/获取属性值,需要关闭arc模式
    fprintf(stdout, 
设置/获取属性值
);
    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

 

五、方法

1.源代码
全局方法:

nsstring *classaddmethodimp(id self, sel _cmd, nsstring *str) {
    // implementation ....
    nslog(@值:%@, str);
    return str;
}

nsstring *username(id self, sel _cmd) {
    return @oc;
}

局部方法:

#pragma mark - 方法
- (void)testmethod
{
    // 获取所有方法
    fprintf(stdout, 获取所有方法
);
    id userclass = objc_getclass(user);
    u_int count;// unsigned int
    method *methods= class_copymethodlist(userclass, &count);// 所有方法,只包含实例方法)
    for (int i = 0; i < count ; i++) {
        method method = methods[i];
        sel name = method_getname(method);// 转为方法
        const char *selname = sel_getname(name);// 转为方法名
        const char *methodtypeencoding = method_gettypeencoding(method);// 方法传输的参数
        char *methodtype = method_copyreturntype(method);// 方法返回的类型
        fprintf(stdout, 方法名:%s; 返回类型%s; 参数:%s
, selname, methodtype, methodtypeencoding);
    }

    // 1.提取method(类方法)
    fprintf(stdout, 
方法提取
);
    sel name = sel_registername(userwithusername:);
    method method = class_getclassmethod(userclass, name);
    name = method_getname(method);
    fprintf(stdout, 提取方法(+):%s
, sel_getname(name));
    // 2.提取method(实例方法)
    name = sel_registername(initwithusername:);
    method = class_getinstancemethod(userclass, name);
    name = method_getname(method);
    fprintf(stdout, 提取方法(-):%s
, sel_getname(name));
    // 3.提取imp
    imp imp = method_getimplementation(method);
    // 只能获取(-)方法
    imp = class_getmethodimplementation(userclass, name);
    imp = class_getmethodimplementation_stret(userclass, name);
    // 等价
    user *user = [[user alloc] init];
    imp = [user methodforselector:name];

    // 类增加方法(全局方法)
    fprintf(stdout, 
类增加方法
);
    name = sel_registername(classaddmethodimp);
    bool addmethod = class_addmethod(userclass, name, (imp)classaddmethodimp,i@:@);
    // 判断类是否有此方法
    if (addmethod && class_respondstoselector(userclass, name) && [user respondstoselector:name]) {
        fprintf(stdout, 类%s添加方法%s成功
, class_getname(userclass), sel_getname(name));
    }
    // 类添加方法(-)
    name = @selector(classaddmethod:);
    method = class_getinstancemethod(self.class, name);// 方法体
    imp = method_getimplementation(method);// 方法的实现
    class_addmethod(userclass, name, imp, v@:);
    // 方法调用
    id methodback = [user performselector:@selector(classaddmethod:) withobject:@阳君];
    nslog(@类%@调用方法%@ 返回:%@, nsstringfromclass(user.class), [nsstring stringwithcstring:sel_getname(name) encoding:nsutf8stringencoding], methodback);

    // 方法交换
    fprintf(stdout, 
方法交换
);
    method m1 = class_getinstancemethod([self class], @selector(username));
    method m2 = class_getinstancemethod([self class], @selector(username2));
    method_exchangeimplementations(m1, m2);
    nslog(@%@, [self username]);
    nslog(@%@, [self username2]);

    // 方法替换
    fprintf(stdout, 
方法替换
);
    method usernamemethod = class_getinstancemethod(self.class, @selector(username));
    imp usernameimp = method_getimplementation(usernamemethod);
    method setusernamemethod = class_getinstancemethod(self.class, @selector(username2));
    method_setimplementation(setusernamemethod, usernameimp);
    nslog(@%@, [self username]);
    nslog(@%@, [self username2]);

    // 方法覆盖,只能使用全局方法替换,方法名需要一致
    fprintf(stdout, 
方法覆盖
);
    nslog(@%@, user.username);
    name = sel_registername(username);
    imp = class_replacemethod(userclass, name, (imp)username,i@:@);
    nslog(@%@, user.username);
}

#pragma mark 覆盖的方法
- (nsstring *)username
{
    return @阳君;
}

- (nsstring *)username2
{
    return @ios;
}

#pragma mark 增加的方法
- (nsstring *)classaddmethod:(nsstring *)str
{
    return str;
}


2.输出
获取所有方法
方法名:initwithusername:; 返回类型@; 参数:@24@0:8@16
方法名:username; 返回类型@; 参数:@16@0:8
方法名:setusername:; 返回类型v; 参数:v24@0:8@16

方法提取
提取方法(+):userwithusername:
提取方法(-):initwithusername:

类增加方法
类user添加方法classaddmethodimp成功
2015-09-23 10:21:19.167 runtime[14182:685354] 类user调用方法classaddmethod: 返回:阳君

方法交换
2015-09-23 10:21:19.168 runtime[14182:685354] ios
2015-09-23 10:21:19.168 runtime[14182:685354] 阳君

方法替换
2015-09-23 10:21:19.168 runtime[14182:685354] ios
2015-09-23 10:21:19.168 runtime[14182:685354] ios

方法覆盖
2015-09-23 10:21:19.169 runtime[14182:685354] (null)
2015-09-23 10:21:19.169 runtime[14182:685354] oc

 

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网