iOS runtime探究(三): 从runtime開始理解OC的属性property
你要知道的runtime都在这里
转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303
本文主要解说runtime相关知识,从原理到实践。因为包括内容过多分为下面五篇文章具体解说,可自行选择须要了解的方向:
- 从runtime開始: 理解面向对象的类到面向过程的结构体
- 从runtime開始: 深入理解OC消息转发机制
- 从runtime開始: 理解OC的属性property
- 从runtime開始: 实践Category加入属性与黑魔法method swizzling
- 从runtime開始: 深入weak实现机理
本文是系列文章的第三篇文章从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_getName和property_getAttributes方法获取该属性描写叙述的name和attributes值,输出的结果例如以下:
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的更多相关文章
- iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制
你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识, ...
- (转发)IOS高级开发~Runtime(三)
11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selec ...
- 李洪强iOS经典面试题156 - Runtime详解(面试必备)
李洪强iOS经典面试题156 - Runtime详解(面试必备) 一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...
- iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.
Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...
- iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.
引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...
- 从零開始学android<数据存储(1)SharedPreferences属性文件.三十五.>
在android中有五种保存数据的方法.各自是: Shared Preferences Store private primitive data in key-value pairs. 相应属性的键值 ...
- iOS中从零開始使用protobuf
让我们一起打开以下这个链接 https://github.com/alexeyxo/protobuf-objc 在github上有protobuf-objc,当中的readme能够教会我们安装prot ...
- 今天開始慢下脚步,開始ios技术知识的查漏补缺。
从2014.6.30 開始工作算起. 如今已经是第416天了.不止不觉.时间过的真快. 通过对之前工作的总结.发现,你的知识面.会决定你面对问题时的态度.过程和结果. 简单来讲.知识面拓展了,你才干有 ...
- iOS开发黑科技之runtime
iOS 开发之黑科技-runtime runtime其实就是oc底层的一套C语音的API 调用方法的本质就是发消息, 1.动态交换两个方法的实现(特别是交换系统自动的方法) 2.动态添加对象的成员变量 ...
随机推荐
- C语言sscanf和sprintf输入输出使用及Strlen、Memset解释
sscanf() - 从一个字符串中读进与指定格式相符的数据. swscanf()- 用于处理宽字符字符串,和sscanf功能相同 通过学习和使用个人认为,在字符串格式不是很复杂,但是也并不 ...
- STM32学习日志--使用DMA功能自动更新PWM的输出
/******************************************************************************* 编译环境: EWARM V5.30 硬 ...
- 聚币网API使用教程 demo
原文 http://30daydo.com/article/181 目前还在完善,等功能完善了,就更新到csdn. 更新 2017-05-27 官方有API的文档,可是这个文档就像一个草稿一样,两个基 ...
- 如何利用 jQuery 修改 css 中带有 !important 的样式属性?
使用 jQuery 修改 css 中带有 !important 的样式属性 外部样式为: div.test { width:auto !important; overflow:auto !import ...
- CentOS 6.8 搭建 Git 代码托管系统 Gitea
[荐] Gitea:Git with a cup of tea,在 Gogs 基础上,发展起来的 自助 Git 服务系统.Gogs是一个个人维护的版本,而Gitea是一个社区组织维护的,版本迭代更新快 ...
- sigmod2017.org
http://sigmod2017.org/sigmod-program/#ssession20
- 自定义两行可左右滑动的GridView
效果图: xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- Maven 使用了一个标准的目录结构和一个默认的构建生命周期。
Maven 使用了一个标准的目录结构和一个默认的构建生命周期. 约定优于配置 当创建 Maven 工程时,Maven 会创建默认的工程结构.开发者只需要合理的放置文件,而在 pom.xml 中不再需要 ...
- mybatis学习之路----批量更新数据两种方法效率对比
原文:https://blog.csdn.net/xu1916659422/article/details/77971696/ 上节探讨了批量新增数据,这节探讨批量更新数据两种写法的效率问题. 实现方 ...
- Android之 MTP框架和流程分析
概要 本文的目的是介绍Android系统中MTP的一些相关知识.主要的内容包括:第1部分 MTP简介 对Mtp协议进行简单的介绍.第2部分 MTP框架 介绍 ...