为何Objective-C编写的xcframework中assign属性在Swift调用时会崩溃
问题解释
为什么使用assign修饰符会导致Swift中调用代码崩溃
assign修饰Objective-C对象类型属性时,仅做指针值拷贝,既不会强持有指向的对象,也不会在对象释放时自动将指针置为nil,属于完全手动管理的指针关联。- 你在Swift代码中执行
config.name = "varun_bindal"时,生成的字符串是Swift管理的临时对象:赋值给assign属性时,ObjC侧不会增加引用计数,Swift侧ARC判断该字符串没有被其他强引用持有,赋值完成后就会自动回收该对象。 - 后续访问
_name时,指针指向的内存已经被释放,就触发了EXC_BAD_ACCESS野指针错误。
补充:纯Objective-C项目中没触发崩溃,大概率是因为你测试时赋值的是
@"xxx"格式的静态常量字符串,这类字符串存储在程序常量区,生命周期和App一致,即使是assign指针指向它也不会出现野指针问题。
为什么移除assign修饰符后代码可以正常运行
- ARC环境下,Objective-C未显式指定修饰符的对象属性,默认使用
strong修饰符:strong会强持有赋值的对象,只要Config实例本身没有被释放,name属性指向的字符串就不会被ARC回收,自然不会出现野指针访问。
最佳实践建议
- 对于
NSString、NSArray这类存在可变子类的属性,推荐使用copy修饰符,避免外部传入可变子类实例后被意外修改,导致不可预期的问题,正确的属性定义如下:
@property(nonatomic, copy, readwrite) NSString *name; @property(nonatomic, copy, readwrite) NSString *id; @property(nonatomic, copy, readwrite) NSString *api;
- 只有
int、NSInteger、CGFloat等基础数据类型才适合使用assign修饰符,对象类型除非特殊需求,不要使用assign。
内容的提问来源于stack exchange,提问作者Alwaysblue
相关产品推荐
相关产品推荐

