使用Theos搭配iOS 10 SDK开发Tweak时遇属性与访问器类型不匹配语义错误
解决iOS Tweak开发中属性与Accessor类型不匹配的语义错误
嘿,我一眼就揪出问题所在了——你的属性定义和手动声明的setter方法类型不匹配,再加上readonly属性的设置也和你想实现setter的需求冲突了。咱们一步步理清楚:
错误根源分析
- 你的
systemVersion属性声明的是NSString *类型,但手动写的setter方法- (void)setSystemVersion:(id)arg1参数是id类型,这就导致编译器判定属性和accessor的类型不一致,直接抛出语义错误。 - 另外,你给属性标记了
readonly,这意味着编译器默认不会生成setter方法,而你自己手动添加了setter,这本身就和readonly的语义矛盾(除非你是想对外只读但内部可写,但你的场景明显是要支持外部设置)。
修正方案
按照下面的步骤调整代码就能解决问题:
- 修正setter的参数类型:把setter的参数从
id改成NSString *,和属性类型严格保持一致。 - 调整属性的读写权限:如果需要外部能调用这个setter,把
readonly改成readwrite;如果只是内部需要设置,也可以保持readonly但在类扩展里重新声明为readwrite(不过你的场景直接改readwrite更直观)。 - 补全属性合成语句:
@synthesize后面要完整写systemVersion = _systemVersion,别只写半截_...。
修正后的完整代码
头文件部分
@interface ALDevice : NSObject { NSString *_systemVersion; } @property(readwrite, nonatomic) NSString *systemVersion; - (void)setSystemVersion:(NSString *)arg1; @end
实现部分
@implementation ALDevice @synthesize systemVersion = _systemVersion; // 如果你需要自定义setter逻辑,可以在这里实现;不需要的话编译器会自动生成默认实现 - (void)setSystemVersion:(NSString *)arg1 { if (_systemVersion != arg1) { _systemVersion = [arg1 copy]; } } // 自定义getter逻辑同理,按需实现 - (NSString *)systemVersion { return _systemVersion; } @end
额外适配Tweak开发的小提示
如果你的ALDevice是系统类,你是用Theos做Hook扩展的话,更规范的写法是用类扩展来添加属性:
@interface ALDevice () @property(readwrite, nonatomic) NSString *systemVersion; @end @implementation ALDevice (MyTweakExtension) @synthesize systemVersion = _systemVersion; // 实现setter和getter逻辑... @end
内容的提问来源于stack exchange,提问作者Tien Minh




