Objective-C的@property、@synthesize和@dynamic

栏目: Objective-C · 发布时间: 5年前

内容简介:objc推荐我们通过set/get方法访问对象的属性。很显然,为每一个属性手动添加set/get方法的声明和实现是个性价比很低的重复劳动。因此,objc提供了一些关键字帮助我们简化这一过程。实际上就是这么回事儿。首先来看现在的property:例如:

objc推荐我们通过set/get方法访问对象的属性。很显然,为每一个属性手动添加set/get方法的声明和实现是个性价比很低的重复劳动。因此,objc提供了一些关键字帮助我们简化这一过程。实际上就是这么回事儿。

@property

首先来看现在的property:

例如:

@interface ViewController : UIViewController
@property (nonatomic,assign) BOOL testVar;
@end

简单理解,相当于声明了成员变量 _testVar ,声明了实现了set方法 setTestVar 、get方法 testVar ,等价于:

@interface ViewController : UIViewController
{
    BOOL _testVar;
}
- (void)setTestVar:(BOOL)newTestVar;
- (BOOL)testVar;
@end

@implementation ViewController
- (void)setTestVar:(BOOL)newTestVar
{
    _testVar = newTestVar;
}
- (BOOL)testVar
{
    return _testVar;
}
@end

@synthesize

@synthesize可以指定set/get方法的实现。

1. 默认

默认地,@synthesize会生成一个同名的成员变量作为set/get的目标。

例如:

@interface ViewController : UIViewController
@property (nonatomic,assign) BOOL testVar;
@end
  
@implementation ViewController
@synthesize testVar;
@end

等价于:

@interface ViewController : UIViewController
{
    BOOL testVar;
}
- (void)setTestVar:(BOOL)newTestVar;
- (BOOL)testVar;
@end

@implementation ViewController
- (void)setTestVar:(BOOL)newTestVar
{
    testVar = newTestVar;
}
- (BOOL)testVar
{
    return testVar;
}
@end

可以看到,set/get方法指向了成员变量 testVar ,也不会再默认生成 _testVar

注意,很多人误认为@synthesize默认生成的成员变量是 _testVar ,据我所知这是不对的。

官方文档

Important:If you use @synthesize without specifying an instance variable name, like this:

@synthesize firstName;

the instance variable will bear the same name as the property.

In this example, the instance variable will also be called firstName , without an underscore.

2. 指定

@synthesize也可以指定一个成员变量作为其set/get的目标。

例如:

@interface ViewController : UIViewController
{
    BOOL exampleVar;
}
@property (nonatomic,assign) BOOL testVar;
@end
  
@implementation ViewController
@synthesize testVar = exampleVar;
@end

等价于:

@interface ViewController : UIViewController
{
    BOOL exampleVar;
}
- (void)setTestVar:(BOOL)newTestVar;
- (BOOL)testVar;
@end

@implementation ViewController
- (void)setTestVar:(BOOL)newTestVar
{
    exampleVar = newTestVar;
}
- (BOOL)testVar
{
    return exampleVar;
}
@end

此时set/get方法就指向了成员变量 exampleVar

特别的,可以声明并指定成员变量 _testVar ,例如:

@interface ViewController : UIViewController
{
    BOOL _testVar;
}
@property (nonatomic,assign) BOOL testVar;
@end

@implementation ViewController
@synthesize testVar = _testVar;
@end

这是最符合官方规范的做法:每个属性对应一个以 _ 开头的成员变量。

可以看出,这种写法跟本文第一部分,只写一个 @property 的作用是一样的。

一点历史

其实,在xcode4.4(对应clang3.2/LLVM4.0)以前,显式声明 _testVar@synthesize testVar = _testVar; 是标准做法。那时候只写个 @property 并不会给你带来成员变量和set/get的实现。

现在的表现是编译器把以前的标准做法化作默认行为的结果。当我们只声明了 @property 而没有实现对应的set/get方法时,编译器会默认声明 _ 开头的成员变量并补全set/get的实现。

一个真实案例

最近遇到的问题是一坨老代码,里面用了 @synthesize 但是似乎不是很规范,后来维护的人看起来也不太熟悉这几个关键字,照着前人的代码瞎写,最后代码类似下面的:

@interface ViewController : UIViewController
{
    BOOL _testVar;
}
@property (nonatomic,assign) BOOL testVar;
@end

@implementation ViewController
@synthesize testVar;
- (void)viewDidLoad {
    [super viewDidLoad];
    self.testVar = YES;
    if(_testVar){
        [self doSomething];
    }
}
@end

可以看到,代码逻辑里用 _testVar 去做条件判断其实是完全无效的。

@dynamic

@dynamic的作用是告诉编译器,此属性对应的set/get方法将会被动态提供。

说得明白一点,其实@dynamic做了两件事:

  1. set/get我会自己提供的,不用帮我生成了
  2. 我会动态提供,没直接写在这里,编译器别给我报错

通常如果用到dynamic的话,这些方法会在消息转发的时候处理,也可以通过runtime的一些机制动态插入。 这里 有一些例子。

一般开发中基本上不会用到。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Software Engineering for Internet Applications

Software Engineering for Internet Applications

Eve Andersson、Philip Greenspun、Andrew Grumet / The MIT Press / 2006-03-06 / USD 35.00

After completing this self-contained course on server-based Internet applications software, students who start with only the knowledge of how to write and debug a computer program will have learned ho......一起来看看 《Software Engineering for Internet Applications》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具