当前位置: 首页 > news >正文

什么情况下用分类?分类的优缺点?分类怎么用属性?关联对象的原理?关联策略?分类怎么实现一个weak属性?

下面这套回答,基本就是 iOS 高级工程师面试​ 里关于 Category(分类)​ 的标准高分答案,既讲清楚「是什么」,也讲清楚「为什么」和「底层原理」。

一、什么情况下用分类(Category)?

常见使用场景:
  1. 给系统类或第三方类扩展功能
    • 不继承、不改源码
    • 例如:UIView+FrameNSString+EncryptNSArray+Safe
  2. 拆分臃肿的类
    • 把一个巨型 .m按职责拆成多个 Category
    • 提高可维护性、可读性
  3. 声明私有方法 / 非正式协议
    • 早期用于 delegate(现在多用 protocol)
    • 仍常见于内部实现细节隐藏
  4. 解耦业务模块
    • 不同业务线维护不同 Category
    • 避免主类无限膨胀
总结一句话
当你想“扩展已有类的功能,而不是新建一个子类”时,优先考虑 Category。

二、分类的优缺点

✅ 优点

 
优点
说明
无需继承
不影响原有继承体系
使用简单
引入头文件即可
运行时动态
运行时合并方法
解耦
可按功能拆分

❌ 缺点 & 风险

  1. 不能添加成员变量(ivars)
    • 只能添加方法
    • 实例变量在编译期确定,无法动态添加
  2. 同名方法覆盖风险
    • Category 方法会“覆盖”原类方法
    • 多个 Category 同名方法 → 结果不确定(后编译的生效)
  3. +load 顺序不可控
    • 多个 Category 的 +load执行顺序不明确
  4. 可读性下降
    • 方法散落在多个文件中
    • 不利于新人理解调用链
面试加分点
Category 不是用来替代子类的,而是用来“增强”,不能表达 is-a 关系

三、分类中怎么使用属性(@property)?

1️⃣ 直接声明 @property会发生什么?

@interface NSObject (MyCategory)
@property (nonatomic, copy) NSString *name;
@end
只会生成声明,不会生成:
  • 实例变量
  • getter / setter 实现
➡️ 直接访问会 编译报错 / crash

2️⃣ 正确做法:关联对象(Associated Object)

#import <objc/runtime.h>@implementation NSObject (MyCategory)- (void)setName:(NSString *)name {objc_setAssociatedObject(self,@selector(name),name,OBJC_ASSOCIATION_COPY_NONATOMIC);
}- (NSString *)name {return objc_getAssociatedObject(self, @selector(name));
}@end
本质
属性只是语法糖,Category 中用关联对象“手动实现”存取器。

四、关联对象(Associated Object)原理

1️⃣ 核心 API

void objc_setAssociatedObject(id object,const void *key,id value,objc_AssociationPolicy policy);id objc_getAssociatedObject(id object,const void *key);void objc_removeAssociatedObjects(id object);

2️⃣ 底层存储结构(面试常问)

  • 每个对象都有一个 Associations HashMap
  • key 是 void *
  • value 是 ObjcAssociation(包含值和策略)
简化模型:
Object└── Associations├── key1 → value1├── key2 → value2
关键点
  • 关联对象 不在对象内存布局中
  • 由 runtime 统一管理
  • 生命周期 跟随对象销毁

五、关联策略(objc_AssociationPolicy)

 
策略
等价属性
OBJC_ASSOCIATION_ASSIGN
assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC
strong, nonatomic
OBJC_ASSOCIATION_COPY_NONATOMIC
copy, nonatomic
OBJC_ASSOCIATION_RETAIN
strong, atomic
OBJC_ASSOCIATION_COPY
copy, atomic
⚠️ 没有 weak 策略

六、分类怎么实现一个 weak 属性?

❌ 错误认知

runtime 不支持 OBJC_ASSOCIATION_WEAK

✅ 正确实现方式:中间对象 + weak 引用

思路

  1. 用一个中间对象持有 weak指针
  2. 关联对象 strong 持有这个中间对象
  3. 中间对象内部用 __weak

✅ 示例代码

@interface WeakContainer : NSObject
@property (nonatomic, weak) id weakObject;
@end@implementation WeakContainer
@end
- (void)setWeakObj:(id)obj {WeakContainer *container = [[WeakContainer alloc] init];container.weakObject = obj;objc_setAssociatedObject(self,@selector(weakObj),container,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (id)weakObj {WeakContainer *container =objc_getAssociatedObject(self, @selector(weakObj));return container.weakObject;
}
这是面试标准答案

七、高级面试追问(加分项)

Q:Category 和 Extension 区别?

 
对比
Category
Extension
能否加属性
需关联对象
可直接
能否加 ivar
编译期
运行时
编译期
是否必须实现

Q:Category 为什么不能添加成员变量?

  • 对象内存布局在 编译期确定
  • runtime 不支持动态增加 ivar

Q:Category 方法存在哪?

  • 存放在 Category 自己的 method list
  • 运行时合并到类的方法列表中
  • 插入在方法列表前面(优先级高)

八、一句话总结(面试收尾)

Category 适合扩展行为,不适合扩展状态;属性需用关联对象实现;runtime 无 weak 关联策略,只能通过中间对象间接实现 weak。
如果你需要,我可以帮你把这一套整理成 面试逐字稿版​ 或 技术雷达图版,方便直接背诵。
http://www.jsqmd.com/news/897704/

相关文章:

  • Node.js 服务端项目如何集成 Taotoken 实现异步 AI 功能调用
  • 2026年河南标识标牌厂推荐:前期标识一站式解决医院商场痛点 - 资讯速览
  • CentOS 7上搞定NUMECA Fine 10.1:从下载到破解的保姆级避坑实录
  • 2026广东、佛山五大二手手表回收推荐:2026最新排名出炉,玩表世家以全产业链实力领先 - 十大品牌榜
  • 国内主流潜水推流器厂商综合实力排行盘点 - 奔跑123
  • 免费开源Mac应用大全:689款精选工具完全指南
  • 基于YOLO模型的实时目标检测与告警系统:Python实现与SQLite存储
  • 不懂携程任我行礼品卡变现?手把手教你轻松搞定! - 团团收购物卡回收
  • 泸州黄金变现哪家强 长悦领跑值得信赖 优选长悦 - 专业黄金回收
  • Adobe-GenP 3.0终极指南:如何免费使用Adobe Creative Cloud全系列软件
  • 2026湖南非开挖修复材料公司选型:守护地下管网的隐形防线 - 奔跑123
  • 618必囤发膜:高性价比的宝藏发膜 - 资讯速览
  • 构建跨平台翻译与OCR应用:基于Tauri和React的Pot Desktop开发实战
  • 从闲置旧电脑到家庭NAS:手把手教你用Openfiler打造私人影音库和备份中心
  • 2026年武汉宜昌襄阳高端名表维修服务全攻略:从劳力士欧米茄到本地修表店的理性选择指南 - 优质企业观察收录
  • 戴森球计划FactoryBluePrints蓝图仓库:8000+工厂蓝图打造高效星际帝国
  • python3-01-base
  • Turnitin降AI还在瞎折腾?实测避坑:3款高效工具助你从80%稳降至10%
  • 发膜真实用户报告:大数据揭秘哪款卖最好 - 资讯速览
  • SPSS实战:卡方检验在医学研究中的分布验证
  • 新沃李晓伟律师团队,让沈阳保险拒赔法律纠纷一键化解 - 行路心安
  • UniversalUnityDemosaics终极指南:免费去除Unity游戏马赛克
  • 2026年AI搜索引流哪家强?选服务商需要避开这三个误区 - FaiscoJeff
  • 绵阳黄金回收门店怎么选靠谱商家看这篇长悦领跑 优选长悦 - 专业黄金回收
  • 使用AI教材写作工具,轻松搞定教材编写,还能保证低查重率!
  • 2026三亚目的地婚礼全新最终版攻略|滨海婚礼品牌排名+选店避坑完整版 - 江湖评测
  • 2026年OpenClaw翻车后的最佳替代选择,支持私有化部署替代方案推荐:速+X综合智能体系统1.0 - 品牌2025
  • ChatGPT谜题解答成功率暴跌预警(2024Q2实测数据:未结构化提问导致47.6%失败率)
  • 2026 国内广东佛山地区五大包装印刷推荐:2026 最新排名出炉,佛山市千寻包装印刷有限公司以综合实力领先 - 十大品牌榜
  • 给新手的华为云Region、VPC、AZ选择指南:从概念到实战,看完就懂