You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Objective-C的Work类中防止修改传入的UserSettings实例属性?

解决OC中限制类内对外部对象属性修改的问题

这个场景我太熟悉了——你想让Work类持有UserSettings但只能读不能改,之前用readonly和const没效果,核心原因是这俩都没限制到UserSettings对象自身的属性读写权限,只是限制了Work类里的指针或属性赋值。下面给你两个靠谱的解决方案,都能触发编译错误,从根源上阻止修改操作:

方案一:用只读协议约束接口

这是最通用的做法,适合多个类都需要只读访问UserSettings的场景:

  1. 先定义一个只包含只读属性的协议:
// UserSettingsReadOnly.h
@protocol UserSettingsReadOnly <NSObject>
@property (nonatomic, readonly, copy) NSString *color;
// 把UserSettings里所有需要暴露给Work的属性都以readonly声明在这里
@end
  1. 让你的UserSettings类遵守这个协议:
// UserSettings.h
#import "UserSettingsReadOnly.h"

@interface UserSettings : NSObject <UserSettingsReadOnly>
// 这里保留原有的readwrite属性,外部依然可以正常修改
@property (nonatomic, copy) NSString *color;
// 其他读写属性...
@end
  1. 在Work类里用协议类型来持有settings:
// Work.m
@interface Work()
@property (nonatomic, strong) id<UserSettingsReadOnly> settings;
@end

@implementation Work
- (instancetype)initWithSettings:(UserSettings *)settings {
    if (self = [super init]) {
        _settings = settings;
        // 尝试修改会直接触发编译错误:Property 'color' is readonly
        // self.settings.color = @"red"; 
    }
    return self;
}
@end

原理:编译器在Work类里只会识别UserSettingsReadOnly协议里的只读属性,所以任何修改属性的操作都会被拦截,而外部给Work传UserSettings对象完全没问题,因为它遵守了协议。

方案二:用私有类别缩小可见范围

如果只有Work类需要这个限制,不想多写一个协议文件,可以在Work的实现文件里给UserSettings加一个私有类别:

// Work.m
// 私有类别,只在当前文件生效
@interface UserSettings (ReadOnlyForWork)
@property (nonatomic, readonly, copy) NSString *color;
@end

@interface Work()
@property (nonatomic, strong) UserSettings *settings;
@end

@implementation Work
- (instancetype)initWithSettings:(UserSettings *)settings {
    if (self = [super init]) {
        _settings = settings;
        // 同样会触发编译错误:Property 'color' is readonly
        // self.settings.color = @"red";
    }
    return self;
}
@end

原理:这个私有类别会覆盖Work类对UserSettings属性的认知,编译器认为color是只读的,自然不允许修改。外部代码不受任何影响,因为这个类别只在Work.m里可见。

为什么之前的方法没用?

  • @property(readonly) UserSettings * settings;:这个只是限制了Work类不能重新赋值settings指针(比如不能写self.settings = newSettings),但UserSettings对象本身的color属性还是readwrite的,所以修改依然可行。
  • const UserSettings * _settings;:OC里的const是指针常量,意思是不能修改_settings指向的地址,但指针指向的对象的属性依然可以修改——OC没有像C++那样的对象级const约束,所以这个方法无效。

内容的提问来源于stack exchange,提问作者Heefan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:50:56