关于iOS Category实现添加属性及成员变量
iOS分类:
很多说法是只能添加方法,而不能添加成员变量或属性。
有些人可能知道,这种说法是不严谨的,并不是绝对不能添加变量。
解释如下:
我们知道在一个类中用@property声明属性,编译器会自动帮我们生成_成员变量和setter/getter,但分类的指针结构体中,根本没有属性列表。所以在分类中用@property声明属性,既无法生成_成员变量也无法生成setter/getter。
因此结论是:我们可以用@property声明属性,编译会通过,但run之后就会崩溃。
问题来了。。
既然报错的根本原因是使用了系统没有生成的setter/getter方法,可不可以在手动添加setter/getter来避免崩溃,完成调用呢?
其实是可以的。由于OC是动态语言,方法真正的实现是通过runtime完成的,虽然系统不给我们生成setter/getter,但我们可以通过runtime手动添加setter/getter方法。那具体怎么实现呢?
举例如下:
分类.h
#import "Programmer.h" @interface Programmer (Category) @property(nonatomic,copy) NSString *nameWithSetterGetter; //设置setter/getter方法的属性 - (void) programCategoryMethod; //分类方法 @end
分类.m
#import "Programmer+Category.h"
#import <objc/runtime.h> static NSString *nameWithSetterGetterKey = @"nameWithSetterGetterKey";
@implementation Programmer (Category)
- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter {
objc_setAssociatedObject(self, &nameWithSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY);
}
- (NSString *)nameWithSetterGetter {
return objc_getAssociatedObject(self, &nameWithSetterGetterKey);
} - (void)programCategoryMethod {
NSLog(@"实现分类方法");
}
@end
重点就是两个runtime实现方法,如果不写这个,只要你申明了属性,运行肯定会报错;如果加了这两个方法,就能运行通过了,而且,我们在其他地方也能正常使用了
Programmer *programmer = [[Programmer alloc]init];
//通过runtime实现了setter/getter
programmer.nameWithSetterGetter = @"有setter/getter"; //调用setter,成功
NSLog(@"%@",programmer.nameWithSetterGetter); //调用getter,成功
关于iOS Category实现添加属性及成员变量的更多相关文章
- 让Category支持添加属性与成员变量【转载】
Category是Objective-C中常用的语法特性,通过它可以很方便的为已有的类来添加函数.但是Category不允许为已有的类添加新的属性或者成员变量. 一种常见的办法是通过runti ...
- iOS的Runtime机制下给类别(category)添加属性、替换原有类的方法执行
一.Runtime的理解 OC是面向对象的语言这是常识,其实就是通过Runtime机制动态创建类和对象,这里只是简单的运用runtime的使用! 二.类别(category)添加属性_使用前记得导入头 ...
- IOS学习5——属性与成员变量
[转]iOS中属性与成员变量的区别 ios中属性修饰符的作用 1. 属性用property声明 2. 简而言之,对于目前的ios开发,属性和成员变量的区别,完全可以不管. 3. 这个是历史原因造成的. ...
- Objective-C的属性和成员变量用法及关系浅析
在使用Objective-C语言进行了一段时间的iOS开发之后,发现自己的语言基础相对薄弱,于是开始弥补自己的短处.我发现在用过一种语言之后,再回过头来看它的很多原理会发现有更加深刻的理解.下面就对一 ...
- OC中在.h和.m中声明的属性和成员变量有何区别?
相比Swift而言,OC规矩太多. 差不多,.h中声明的属性和成员变量均可以在子类中访问到.而.m则不可.而属性其实也就是成员变量的一种简写,其内部自动包含了getter和setter方法. 如图:V ...
- Object-c中的属性和成员变量的关系详解
很多人在初学移动开发的时候会对object-c中的合成存取方法感到疑惑,此处尝试为看到本文有缘人答疑解惑,鄙人才疏学浅,难免有疏漏谬误之处,热烈欢迎诸位看官拍砖指点. 1.合成存取方法: OC为增加开 ...
- JavaBean属性和成员变量的区别和联系
JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中.特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性.名称中的“Bean”是用于 ...
- iOS中属性与成员变量的区别
一.类Class中的属性property 在ios第一版中,我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: @interfa ...
- 【转】iOS中属性与成员变量的区别
[转载自并整理 http://blog.csdn.net/itianyi/article/details/8618128] 一.类Class中的属性property 在ios第一版中,我们为输出口同时 ...
随机推荐
- [翻译] ADPopupView 触摸弹出视窗
ADPopupView 触摸弹出视窗 https://github.com/Antondomashnev/ADPopupView ADPopupView is an iOS drop-in class ...
- Mantis的config_inc.php的各配置项的作用及其修改
Mantis的设置是这样保存的:在 config_defaults_inc.php中保存Mantis的默认设置,用户自己的设置信息保存在config_inc.php中.如果某个选项在config_in ...
- struts2怎么实现页面到页面之间的传值?
我要实现一个产品订购的功能,在浏览产品的时候通过点击一个订购的链接,跳转到提交订单的页面,在跳转的同时要把浏览的产品的名称和型号传到提交订单的页面,并且把这里的订单类的产品名称和型号的表单域里赋上传递 ...
- Tomcat启动就执行特定方法
import java.util.Timer; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContex ...
- Zabbix named 监控
Named 监控 配置 named.conf ,在options 配置节增加如下配置(同时检查/var/named 文件夹权限),然后重启named服务. tatistics-file "/ ...
- 第七章 Xmemcached客户端介绍
提示:有关于XMemcached在实际开发中的具体使用,查看"Java企业项目开发实践"系列博客的<第八章 企业项目开发--分布式缓存memcached> 注意:本文主 ...
- 系统运维技巧(三)——利用dd命令临时增加交换分区
有时会遇到内存不够用的情况,可以使用本文提供的方法进行临时增加交换分区. #制作交换分区——得到文件 [root@serv01 linux-2.6.38]# dd if=/dev/zero of=/s ...
- 创建并发布node.js module
创建node.js module. 创建一个文件夹,用来存放module. Cd到新创建的文件夹,运行npm init,会提示输入package的信息. 可以按照这个视频的来输入.Test com ...
- IStat Menus 5.02 5.03 的注册码
1574-5977-7956-8062-0000 6015-5448-3282-4975-0000 9665-5955-6856-2071-0000 2447-9517-7939-5221-0000
- 线程池线程数与(CPU密集型任务和I/O密集型任务)的关系
近期看了一些JVM和并发编程的专栏,结合自身理解,来做一个关于(线程池线程数与(CPU密集型任务和I/O密集型任务)的关系)的总结: 1.任务类型举例: 1.1: CPU密集型: 例如,一般我们系统的 ...