你要知道的runtime都在这里

转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303

本文主要解说runtime相关知识,从原理到实践。因为包括内容过多分为下面五篇文章具体解说,可自行选择须要了解的方向:

本文是系列文章的第三篇文章从runtime開始: 理解OC的属性property,主要从runtime出发解说属性property相关的底层实现和相关方法,因为之前的博客已经具体解说了property的底层实现,所以本文不再赘述,如有须要能够查看相关文章:iOS @property探究(一): 基础具体解释该文主要解说property的基础以及修饰符具体解释。iOS @property探究(二): 深入理解该文主要深入代码理解property的底层实现。因为与本文的内容由非常大的反复,因此本文不再赘述上述相关内容。

本文将会解说一些runtime操作属性的相关方法。

首先回想一下相关代码以及与property底层实现相关的两个结构体:

//OC自己定义类的定义
@interface Person : NSObject @property (nonatomic, copy) NSString* cjmName;
@property (nonatomic, assign) NSUInteger cjmAge; @end @implementation Person @synthesize cjmName = _cjmName;
@synthesize cjmAge = _cjmAge; @end //clang转写为.cpp的相关代码
struct _prop_t {
const char *name;
const char *attributes;
}; static struct /*_prop_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count_of_properties;
struct _prop_t prop_list[2];
} _OBJC_$_PROP_LIST_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_prop_t),
2,
{{"cjmName","T@\"NSString\",C,N,V_cjmName"},
{"cjmAge","TQ,N,V_cjmAge"}}
};

通过上述代码事实上我们能够看出,一个@property属性在底层就是一个结构体描写叙述,那么我们怎样获取这个结构体呢?能够通过例如以下代码获取:

int main(int argc, const char * argv[]) {
@autoreleasepool {
Person* p = [[Person alloc] init];
p.cjmName = @"Jiaming Chen"; unsigned int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList([p class], &propertyCount);
for (int i = 0; i < propertyCount; i++) {
const char* name = property_getName(propertyList[i]);
const char* attributes = property_getAttributes(propertyList[i]);
NSLog(@"%s %s", name, attributes);
}
}
return 0;
}

首先看一下objc_property_t是什么。在objc/runtime.h中能够找到相关定义:

typedef struct objc_property *objc_property_t;

它是一个指向结构体struct objc_property的指针,这里的结构体struct objc_property事实上就是前文中.cpp文件里的struct _prop_t结构体,通过class_copyPropertyList方法就能够获取到相关类的全部属性。具体函数声明例如以下:

/**
* Describes the properties declared by a class.
*
* @param cls The class you want to inspect.
* @param outCount On return, contains the length of the returned array.
* If \e outCount is \c NULL, the length is not returned.
*
* @return An array of pointers of type \c objc_property_t describing the properties
* declared by the class. Any properties declared by superclasses are not included.
* The array contains \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free().
*
* If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0.
*/
OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

通过凝视能够看出。第一个參数是相关类的类对象(如有疑问能够查阅本系列文章的前两篇文章)。第二个參数是一个指向unsigned int的指针。用于指明property的数量,通过该方法就能够获取到全部的属性,接下来能够通过property_getNameproperty_getAttributes方法获取该属性描写叙述的nameattributes值,输出的结果例如以下:

2017-03-27 09:59:20.914487 OCTest[2467:460742] cjmName T@"NSString",C,N,V_cjmName
2017-03-27 09:59:20.915321 OCTest[2467:460742] cjmAge TQ,N,V_cjmAge

name非常好理解。后面的attributes通过对照不难发现其规律,感兴趣的读者也能够多设置几个不同类型、不同修饰符的property看一下输出。

除此之外哈有一下几个方法用于依据属性名获取一个属性描写叙述结构体、加入属性、替换属性等方法。

/**
* Returns a property with a given name of a given class.
*
* @param cls The class you want to inspect.
* @param name The name of the property you want to inspect.
*
* @return A pointer of type \c objc_property_t describing the property, or
* \c NULL if the class does not declare a property with that name,
* or \c NULL if \e cls is \c Nil.
*/
OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); /**
* Adds a property to a class.
*
* @param cls The class to modify.
* @param name The name of the property.
* @param attributes An array of property attributes.
* @param attributeCount The number of attributes in \e attributes.
*
* @return \c YES if the property was added successfully, otherwise \c NO
* (for example, the class already has that property).
*/
OBJC_EXPORT BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); /**
* Replace a property of a class.
*
* @param cls The class to modify.
* @param name The name of the property.
* @param attributes An array of property attributes.
* @param attributeCount The number of attributes in \e attributes.
*/
OBJC_EXPORT void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0);

举个简单的栗子:

int main(int argc, const char * argv[]) {
@autoreleasepool {
Person* p = [[Person alloc] init];
p.cjmAge = 20;
p.cjmName = @"Jiaming Chen"; unsigned int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList([p class], &propertyCount);
for (int i = 0; i < propertyCount; i++) {
const char* name = property_getName(propertyList[i]);
const char* attributes = property_getAttributes(propertyList[i]);
NSLog(@"%s %s", name, attributes);
}
objc_property_attribute_t attributes = {
"T@\"NSString\",C,N,V_studentIdentifier",
"",
};
class_addProperty([p class], "studentIdentifier", &attributes, 1);
objc_property_t property = class_getProperty([p class], "studentIdentifier");
NSLog(@"%s %s", property_getName(property), property_getAttributes(property));
}
return 0;
}

通过上述方法就能加入一个属性,因为本人水平有限实际开发中没实用过上述方法。具体实际样例也举不出来所以不再过多赘述。

备注

因为作者水平有限,难免出现纰漏,如有问题还请指教。

iOS runtime探究(三): 从runtime開始理解OC的属性property的更多相关文章

  1. iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制

    你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识, ...

  2. (转发)IOS高级开发~Runtime(三)

    11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selec ...

  3. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  4. iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...

  5. iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...

  6. 从零開始学android&lt;数据存储(1)SharedPreferences属性文件.三十五.&gt;

    在android中有五种保存数据的方法.各自是: Shared Preferences Store private primitive data in key-value pairs. 相应属性的键值 ...

  7. iOS中从零開始使用protobuf

    让我们一起打开以下这个链接 https://github.com/alexeyxo/protobuf-objc 在github上有protobuf-objc,当中的readme能够教会我们安装prot ...

  8. 今天開始慢下脚步,開始ios技术知识的查漏补缺。

    从2014.6.30 開始工作算起. 如今已经是第416天了.不止不觉.时间过的真快. 通过对之前工作的总结.发现,你的知识面.会决定你面对问题时的态度.过程和结果. 简单来讲.知识面拓展了,你才干有 ...

  9. iOS开发黑科技之runtime

    iOS 开发之黑科技-runtime runtime其实就是oc底层的一套C语音的API 调用方法的本质就是发消息, 1.动态交换两个方法的实现(特别是交换系统自动的方法) 2.动态添加对象的成员变量 ...

随机推荐

  1. Google的开源C++单元测试框架Google Test

    玩转Google开源C++单元测试框架Google Test系列(gtest)(总) 前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错. 我 ...

  2. c# RSA 加密解密 java.net公钥私钥转换 要解密的模块大于128字节

    有一个和接口对接的任务,对方使用的是java,我方使用的是c#,接口加密类型为RSA,公钥加密私钥解密. 然后就是解决各种问题. 1.转换对方的密钥字符串 由于c#里面需要使用的是xml各式的密钥字符 ...

  3. 如何利用Reveal神器查看各大APP UI搭建层级

    作者 乔同X2016.08.22 19:45 写了3195字,被42人关注,获得了73个喜欢 如何利用Reveal神器查看各大APP UI搭建层级 字数413 阅读110 评论0 喜欢5 title: ...

  4. 《Go语言实战》摘录:6.3 并发 - 竞争状态

    6.3 并发 - 竞争状态

  5. 百度公共dns

    常用公共DNS服务器地址 DNS(Domain Name System),即域名解析系统,作为将域名和IP地址相互映射的一个分布式数据库,能够使人通过相对好记的域名访问网站,而是一串数字.目前国内运营 ...

  6. 教程:如何手动安装Xamarin与Xamarin for VisualStudio

    [2016/4/17更新:如果你下载后发现仍然需要付费才能编译Android/iOS APP,请到文章最下面更新Xamarin for VS和Xamarin Studio到最新的版本.Build201 ...

  7. AngularJS使用angular-formly进行表单验证

    当验证表单中有很多字段时,这时候可能希望把html的生成以及验证逻辑放到controller中,在页面,也许是这样的: <some-form fiedls="vm.someFields ...

  8. IOS NSLog 打印bool值

    输出BOOL值的方法:NSLog(@"%@",YES?@"YES":@"NO");%@输出字符串. NSLog(@"ifReadO ...

  9. ifeq endif

    ifeq ($(PLATFORM_VERSION),4.4)$(info "________________________4.4"); LOCAL_CFLAGS += -DPLU ...

  10. 使用Camera进行拍照 & 后台静默拍照的思路

    Android中的Camera可以用来进行自定义相机.取景框实时预览.拍照等操作.在5.0中,这个类不推荐使用了,新出了一个Camera2,那个东西没怎么研究过,反正一时半会用不到.本篇讲解的是如果用 ...