Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS中OC给Category添加属性

iOS中OC给Category添加属性

作者头像
Cloudox
发布于 2021-11-23 05:22:03
发布于 2021-11-23 05:22:03
1.6K00
代码可运行
举报
文章被收录于专栏:月亮与二进制月亮与二进制
运行总次数:0
代码可运行

引:

很多人知道可以用Category给已有的类添加一些新方法,但是不同于swift中的extension,Objective-C中的Category(类别)是不支持直接添加属性的,那如果就是需要添加新的属性怎么办呢?有一个办法,使用Runtime中的关联对象技术就可以实现。关于Runtime的说明可以查看这篇博客:传送门:OC中Runtime浅析

Category(类别):

对于不熟悉Category的人,这里也先说明一下Category是什么以及怎么创建Category。

由于一些特殊的需要,我们可能要给现有的类添加一些新的方法,这个需求用继承也可以做到,但是会显得比较重,这时候就可以用Category来达到目的,创建一个已有类的Category,可以给这个类添加你需要的方法,在使用的时候,只需要import你创建的Category,在使用的时候还是使用原来的类,但是你会惊奇的发现他支持你自己在Category中添加的方法。

我们看到的一些名为类似“UINavigationController+Cloudox.h”的文件就是类别了。

那么怎么创建类别呢?

在工程中按住command+N来添加新文件,选择Objectiv-C File:

在出来的界面中的File Type选择Category,就是创建类别文件了,File填写我们要加在类别尾巴上的名字,Class选择你要添加类别的已有类,这里我们为UINavigationController添加类别:

类别文件这样就创建成功了。

添加属性

类别可以为已有的类添加方法,但是却不能直接添加属性,因为即使你添加了@property,它既不会生成实例变量,也不会生成setter、getter方法,即使你添加了也无法使用。

所以我们首先需要自己去添加setter、getter方法,这个好办,直接在.m文件里加就可以了,但是要真正添加可以使用的属性,还需要利用Runtime来关联对象,关于关联对象的技术可以看传送门:OC中Runtime浅析,这里只讲怎么用来添加属性,我们在setter方法里关联一个对象,在getter方法里获取对应key关联的对象,就可以啦,代码如下,很简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//UINavigationController+Cloudox.h文件
#import <UIKit/UIKit.h>

@interface UINavigationController (Cloudox)

@property (copy, nonatomic) NSString *cloudox;

@end

//UINavigationController+Cloudox.m文件
#import "UINavigationController+Cloudox.h"
#import <objc/runtime.h>

@implementation UINavigationController (Cloudox)

//定义常量 必须是C语言字符串
static char *CloudoxKey = "CloudoxKey";

-(void)setCloudox:(NSString *)cloudox{
    /*
     objc_AssociationPolicy参数使用的策略:
     OBJC_ASSOCIATION_ASSIGN;            //assign策略
     OBJC_ASSOCIATION_COPY_NONATOMIC;    //copy策略
     OBJC_ASSOCIATION_RETAIN_NONATOMIC;  // retain策略
     
     OBJC_ASSOCIATION_RETAIN;
     OBJC_ASSOCIATION_COPY;
     */
    /*
     关联方法:
     objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
     
     参数:
     * id object 给哪个对象的属性赋值
     const void *key 属性对应的key
     id value  设置属性值为value
     objc_AssociationPolicy policy  使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
     */
    
    objc_setAssociatedObject(self, CloudoxKey, cloudox, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(NSString *)cloudox{
    return objc_getAssociatedObject(self, CloudoxKey);
}


@end

注意要使用Runtime需要 import runtime 的框架,如代码所示。

现在我们试试效果,我们按照平常的方式用UINavigationController包装一个控制器作为根视图:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ViewController *vc = [[ViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    self.window.rootViewController = nav;
    return YES;
}

这个视图控制器中我们需要导入我们的类别文件,然后我们就会发现我们能够通过self.navigationController获取到我们新添加的名为“cloudox”的属性了!我们可以给这个NSString类型的属性赋值,然后获取它进行显示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import "UINavigationController+Cloudox.h"

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Demo";
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    // 给UINavigationController新加的属性赋值
    self.navigationController.cloudox = @"Hey,this is category's new property!";
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(([UIScreen mainScreen].bounds.size.width-300)/2, 100, 300, 50)];
    label.textColor = [UIColor whiteColor];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = self.navigationController.cloudox;
    [self.view addSubview:label];
}

效果如下:

正常获取到并且显示,非常棒。

以上就是给Category添加属性的方法啦,不难,只要了解Runtime中的关联对象技术就可以轻松达到了。


示例工程:https://github.com/Cloudox/CategoryAddPropertyDemo

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/11/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
小程序图片上传到COS,求提供完整的前端+后端java计算签名代码
最后为什么还是返回AccessDenied禁止访问呢?签名的计算过程有问题吗?还是在哪里有问题
用户4518175
2019/03/14
2K1
CDN-COS常见跨域问题汇总
前端开发在使用CDN-COS产品时,经常会遇到应用上的跨域访问,腾讯云COS和CDN两款产品都可以自主设置跨域响应头,但又有一些差异,本文介绍一下常见的访问失败的问题和验证方式。
wainsun
2021/02/23
3.2K0
CDN-COS常见跨域问题汇总
COS 上传图片+水印处理 报错“The specified key does not exist.”
需要在cos桶上传图片的同时对这个图片加水印(存储桶是私有读写,水印模板图片权限继承(私有读))
用户2141488
2023/05/16
3.4K0
配置TKE Pod接入CAM角色访问COS
经常有用户从云主机迁移到容器后,会存在AK安全存放问题,云主机通常支持关联CAM ROLE,无需在业务代码中配置AK密钥,可直接访问云资源,但是容器后,一个节点存在多个Pod,这样就不安全了。本文介绍在TKE中如何为Pod指定cam role,业务代码无需配置AK,直接访问云资源。
Moc_
2023/11/29
7690
利用STS临时密钥服务快速搭建直传页面的实践
作者简介 吴硕卫:腾讯云技术支持工程师,现负责腾讯云存储产品的技术支持专项工作。 为了实现权限分离,提供更细颗粒度的权限控制,有效的控制帐号生效周期,本文通过腾讯云 CAM 产品的 STS(临时访问凭证)来实现部署,调试,验证等一系列的操作体验。 主要介绍基于腾讯云对象存储 COS,如何使用 COS 签名工具和 HTTP 请求工具 Postman 来验证临时密钥的有效性,以及如何快速实现一个 Web 端页面的文件直传功能。服务器上只需要生成和管理访问密钥,无需关心细节,文件数据都存放在腾讯云 COS
云存储
2020/08/07
3.8K0
腾讯云COS C++ SDK使用记录
目前有将服务器指定文件上传的需求, 手头正好有免费的COS资源使用, 于是使用COS作为存储工具
code-x
2022/08/21
8.8K1
CDN-COS常见跨域问题汇总
前端开发在使用CDN-COS产品时,经常会遇到应用上的跨域访问,腾讯云COS和CDN两款产品都可以自主设置跨域响应头,但又有一些差异,本文介绍一下常见的访问失败的问题和验证方式。
wainsun
2020/09/14
4.8K0
利用STS临时密钥服务快速搭建直传页面的实践
为了实现权限分离,提供更细隔离度的权限控制,有效的控制帐号生效周期,本文通过腾讯云CAM产品的STS(临时访问凭证)来实现部署,调试,验证等一系列的操作体验。
吴硕卫
2020/07/28
6.5K2
利用STS临时密钥服务快速搭建直传页面的实践
【玩转腾讯云】cos c++ sdk v5接入项目 避坑指南
1、Poco的安装和编译,依赖本地的openssl库,这个ssl库可能跟项目用的库相冲突(1.0和1.1的openssl库冲突)。
用户2322279
2020/04/24
2.5K0
【玩转腾讯云】cos c++ sdk v5接入项目 避坑指南
KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门
上一期实战课程,我们模拟真实的生产环境实战演示了如何使用 KubeKey 将新增 Worker 节点添加到已有的 Kubernetes 集群 。最终我们部署完成了一套 3 Master 和 3 Worker 节点的 Kubernetes 集群。
运维有术
2023/07/21
1.6K2
KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门
使用无服务器云函数同步COS对象存储的元信息到ES中
本文利用腾讯云提供的Serverless执行环境-无服务器云函数SCF解决了这一问题。
bellen
2019/01/17
10.9K4
使用无服务器云函数同步COS对象存储的元信息到ES中
深入浅出 SSL/TLS 协议
有没有那么一个人,几乎每天都在你身边,但某天发生一些事情后你会突然发现,自己完全不了解对方。对于笔者而言,这个人就是 TLS,虽然每天都会用到,却并不十分清楚其中的猫腻。因此在碰壁多次后,终于决定认真学习一下 TLS,同时还是奉行 Learning by Teaching 的原则,因此也就有了这篇稍显啰嗦的文章。
evilpan
2023/02/12
2K0
深入浅出 SSL/TLS 协议
从零开始的内存马分析——如何骑马反杀(一)
在某次实战攻防中,有一对儿小马和大马,他们两个通过了层层设备,终于打入了内网,只是在砍杀的过程中,露出了马脚,从巨大的流量中,被挖了出来,可是,真的有这么容易吗?真的如我们所愿吗?随着你的越发深入的对木马,流量进行解密,你的心中越发的不安……
亿人安全
2022/08/30
6.7K0
从零开始的内存马分析——如何骑马反杀(一)
Redis-4.0.11集群配置
本文参考官方文档而成:http://redis.io/topics/cluster-tutorial。经测试,安装过程也适用于redis-3.2.0、redis-4.0.11等。
一见
2018/09/30
2.8K0
mysql-8.0.11-winx64 安装配置: mysqld --initialize --console MYSQL:ERROR 1045 (28000): Access denied ...
mysql-8.0.11-winx64 安装配置: mysqld --initialize --console MYSQL:ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost——MySQL5.7修改密码
一个会写诗的程序员
2018/08/17
9.9K0
mysql-8.0.11-winx64 安装配置: mysqld --initialize --console  MYSQL:ERROR 1045 (28000): Access denied ...
100天精通Golang(基础入门篇)——第3天:Go语言的执行原理及常用命令、编码规范和常用工具
在学习和使用Go语言过程中,了解其执行原理和常用命令是非常重要的。同时,编写规范的代码和使用常用工具也是提高开发效率和代码质量的关键。本文将深入探讨Go语言的执行原理,介绍常用的命令,以及详细讲解编码规范和常用工具的使用方法。
猫头虎
2024/04/08
7790
100天精通Golang(基础入门篇)——第3天:Go语言的执行原理及常用命令、编码规范和常用工具
腾讯云COS MCP Server + CodeBuddy ,让你的idea 不止停留在想象中...
最近在一次上班过程中听到了产品经理的抱怨,后来一时兴起就给产品经理写了一篇基于腾讯云CodeBuddy 和 EdgeOne Pages MCP Server帮助产品经理快速落地原型图的示例,给产品经理看后,产品经理表示很满意,在实现上没什么技术上的门槛,效果上远比其自身苦哈哈画两天原型图的效果要好很多,最重要是这个还很快,两句话搞定原型图。
六月的雨在Tencent
2025/05/18
8321
二次元看过来!基于 Serverless 的舞萌音游查分器
前言 社畜下班时刷微信时看到了《Serverless 有一百种玩法,比好玩更好玩》这篇推送,正巧自己最近断断续续在写音游的历史记录存档,趁着这个机会决定参加这次应用开发。 一、什么是 Serverless Framework Serverless Framework 是业界非常受欢迎的无服务器应用框架,开发者无需关心底层资源即可部署完整可用的 Serverless 应用架构。Serverless Framework 具有资源编排、自动伸缩、事件驱动等能力,覆盖编码、调试、测试、部署等全生命周期,帮助开发者
腾讯云serverless团队
2020/11/06
1.4K0
这次不从零了五万字带您,从负零玩转腾讯AI绘画图像生成搭建前后端分离项目
最近 AIGC 火出圈了还记得上次在群里面的大佬们聊到了 AIGC 的话题我滴妈涉及到我的知识盲区了知识听过这个东西就是生成图片所以不怎么感冒.然后最近腾讯云开发者社区发布了腾讯云AI技术专家与传智教育人工智能学科高级技术专家正在联合打造《腾讯云AI绘画-StableDiffusion图像生成》训练营,训练营将通过8小时的学习带你玩转AI绘画的教程我也就去深入了一下. 感兴趣的大佬快来报名学习呀~
杨不易呀
2023/12/10
3.8K28
这次不从零了五万字带您,从负零玩转腾讯AI绘画图像生成搭建前后端分离项目
开胃菜:冰蝎2.0流量分析
c3VjY2Vzcw== 为success NjhhNGQ0NDctYWQ4MC00MWZlLTg2M2YtYjJlZmUwYjkxZmIx 为68a4d447-ad80-41fe-863f-b2efe0b91fb1 与请求重的$centent 值相同
黑伞安全
2020/12/02
13.1K0
开胃菜:冰蝎2.0流量分析
推荐阅读
相关推荐
小程序图片上传到COS,求提供完整的前端+后端java计算签名代码
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验