Objective-C中何时使用@property声明int变量,何时用普通int变量?
Objective-C 头文件中实例变量声明与属性声明的区别及适用场景
核心本质差异
你在头文件中看到的两种写法本质完全不同:
int nameOfVariable是类的实例变量(ivar),属于类的成员存储单元,直接对应内存中的一块存储地址@property int nameOfVariable是属性声明,本质是对存取方法的封装,编译器会根据修饰符自动生成对应的实例变量、getter 读取方法和 setter 写入方法
具体差异对比
1. 访问权限与方式差异
- 实例变量默认是
@protected权限,仅本类和子类内部可以通过->语法访问(比如self->nameOfVariable = 1),外部类默认无法访问,除非显式标记为@public - 属性会自动生成公开的存取方法,外部类可以直接用点语法访问(比如
obj.nameOfVariable = 1),也可以通过调用存取方法的形式访问;类内部可以直接访问编译器自动生成的带下划线前缀的实例变量_nameOfVariable
2. 功能特性差异
- 实例变量仅承担存储功能,没有额外逻辑:直接读写内存地址,不支持值校验、懒加载等自定义逻辑,也不支持 KVO 监听、线程安全控制、自动内存管理等特性
- 属性支持丰富的自定义配置:
- 可以自定义 getter/setter 实现,比如加值校验、变更通知、懒加载等逻辑,调用方无需感知内部实现
- 默认支持 KVO 机制,属性值变更时会自动触发观察者回调
- 可以通过修饰符指定线程安全规则(
atomic默认保证存取原子性,nonatomic取消原子性提升性能) - 对象类型属性可以通过修饰符指定内存管理规则(
strong/weak/copy等),编译器自动生成内存管理代码,无需手动处理引用计数
适用场景
- 除非是极端性能优化场景需要直接操作内存,否则不推荐在头文件中声明公共实例变量,会破坏类的封装性;如果是仅类内部使用的私有变量,建议直接在
.m文件的类扩展中声明实例变量或者私有属性 - 需要对外暴露访问入口、需要自定义存取逻辑、需要 KVO 支持、需要自动内存管理的场景,统一使用
@property声明属性,这也是目前 Objective-C 开发的通用规范
内容的提问来源于stack exchange,提问作者stefanosn
相关产品推荐
相关产品推荐

