Timer扩展使用关联对象时objc_getAssociatedObject始终返回nil问题排查
解决Timer扩展中关联对象返回nil及相关问题
我来帮你梳理下这个Timer扩展关联对象的问题,你遇到的几个坑其实都是关联对象使用中的常见误区,咱们一步步解决:
一、先搞定关联键的稳定性问题
你提到静态常量repeatCounterAddress有时是空字符串,这其实是用错了关联键的类型!关联对象的键需要是内存地址绝对稳定且唯一的指针,用字符串常量很容易因为初始化时机、字符串字面量共享等问题出状况,这也是你遇到键初始化空的核心原因。
正确的做法是用静态void*指针或者静态char变量作为键,比如:
// 推荐写法,地址绝对唯一且稳定 static void *const kRepeatCounterKey = &kRepeatCounterKey;
或者更简单的:
static char kRepeatCounterKey;
这种方式的键是编译期就确定的内存地址,完全不会出现初始化空的情况,是Apple官方推荐的关联对象键用法。
二、彻底确认操作的是同一个Timer实例
你已经排查了部分实例不一致的问题,这里再补几个容易踩坑的点:
- 用
Timer.scheduledTimer(...)或者Timer.init(...)创建实例后,一定要确保设置关联属性和获取属性时,操作的是同一个对象引用,别不小心重新创建了新Timer。 - 注意Timer调用
invalidate()后虽然不会立刻释放,但如果后续不小心拿到了已经失效的Timer实例,虽然关联对象还存在,但逻辑上可能会混淆,建议失效后及时清理关联值。
三、解决关联值重复的问题
关联值重复通常是两个原因:要么键不唯一(上面的问题解决后这个就不存在了),要么设置关联对象时没正确指定内存管理策略。
设置关联值时一定要明确策略,比如你要存储计数器这种基本数据类型,得先包装成NSNumber,再选择合适的策略:
// 设置关联值:用NSNumber包装基本类型,选择RETAIN_NONATOMIC策略 objc_setAssociatedObject(self, kRepeatCounterKey, @(counter), OBJC_ASSOCIATION_RETAIN_NONATOMIC); // 获取关联值:做空判断,避免nil崩溃 NSInteger counter = [objc_getAssociatedObject(self, kRepeatCounterKey) integerValue];
如果是存储对象类型,根据需求选RETAIN或者COPY策略,确保关联值的生命周期符合预期。另外,更新关联值时要先获取当前值再修改,别直接覆盖,避免逻辑错误导致的“重复”假象。
完整可运行的示例代码
给你一个完整的Timer扩展示例,把所有坑都避开了:
#import <Foundation/Foundation.h> @interface Timer (RepeatCounter) @property (nonatomic, assign) NSInteger repeatCounter; @end @implementation Timer (RepeatCounter) // 用稳定的void*指针作为关联键 static void *const kRepeatCounterKey = &kRepeatCounterKey; - (NSInteger)repeatCounter { NSNumber *counterNum = objc_getAssociatedObject(self, kRepeatCounterKey); // 空值时返回默认值0,避免崩溃 return counterNum ? counterNum.integerValue : 0; } - (void)setRepeatCounter:(NSInteger)repeatCounter { // 包装成NSNumber后存储,指定正确的关联策略 objc_setAssociatedObject(self, kRepeatCounterKey, @(repeatCounter), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end
额外小贴士
- 关联属性不是真正的实例变量,别在Timer的
init方法里直接依赖它,得等对象创建完成后再设置。 - 如果需要提前清理关联值,直接给对应键设置nil即可:
objc_setAssociatedObject(self, kRepeatCounterKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC),对象释放时关联值也会自动被清理。
内容的提问来源于stack exchange,提问作者ilan
相关产品推荐
相关产品推荐

