OC语言基础之@property和@synthesize、@dynamic的配合使用

前言

对于程序员而言,@property非常常见,但是@synthesize和@dynamic却很少出现,这两个关键字有什么用呢?需要怎么配合@property使用呢?本文就要讲述这个问题。

一 @property

@property用于在类、分类、协议中定义属性。所谓的属性就是语法糖,编译器在编译的时候,会将属性翻译为对应的代码。分为如下两种情况:

  • 类中的属性,翻译的内容包括:_name的成员变量的声明,set和get方法的声明,set和get方法的实现。
  • 分类和协议中的属性,翻译的内容包括:set和get方法的声明。

注意点1:类中的属性,编译器会自动为我们生成set和get方法,但是如果我们在某个类中同时手动实现了readwrite属性的set和get方法或着readonly属性的get方法的实现,那么编译器就会认为我们接管了自动生成成员变量、set和get方法的工作,就不会自动为我们声明成员变量、实现set和get方法了。在上述情况下,我们会看到编译器如下报错:·

@interface Student : NSObject
@property(nonatomic,assign)int age;
@end

@implementation Student
- (void)setAge:(int)age {
    _age = age;
}
- (int)age{
    return _age;
}
@end

请添加图片描述
编译器提示,没有声明_age。此时,@property的功能只能生成set和get的声明,并不能生成实例变量和set和get的实现。在这种情况下,只能我们自己手动声明实例变量了,有两种方式:
1.自己声明一个实例变量:

@interface Student : NSObject
{
    int _age;
}
@property(nonatomic,assign)int age;
@end

2.利用@synthesize(这一点可以先略过不看,等看完第二部分关于@synthesize的介绍再回头看这里就会明白是咋回事了):

@synthesize age = my_age;

这个问题的官方文档描述如图所示:
请添加图片描述
注意点2:定义在分类和协议中的@property,编译器仅会为我们生成set和get的声明,不会为我们生成实例变量和get和set方法的实现:

  • 分类中的@property需要我们手动实现set和get方法,且其中不能定义成员变量,可以用关联对象的形式变相定义"成员变量"。
  • 协议中的@property,某个类遵守了这个协议,那么这个类就需要手动实现set和get方法以及定义成员变量,或者使用@synthesize让编译器自动合成。
二 @synthesize

@synthesize只能出现在类的@implementation中,格式是@synthesize 属性名 = 实例变量名,其中实例变量名可以省略,那么生成的实例变量名将和属性名保持一致,如下代码所示:

@synthesize age;
@synthesize name = my_name;

等同于如下代码:

@synthesize age = age;
@synthesize name = my_name;

@synthesize有什么用呢?@synthesize的第一个参数必须是已经定义的属性名,也就是说,它只能用于已经定义的@property,它会为属性声明指定名字的成员变量,为属性生成get和set方法的实现。到这里我们不禁困惑,类中的@property不是已经做了这些工作了吗,@synthesize存在的意义是是什么?Apple为什么要这么设计呢?其实这是有历史原因的:

  • xcode4.4之前,@property只负责set方法和get方法的声明,并不负责实例变量的定义、set和get方法的实现。需要通过@synthesize来定义实例变量和生成set和get方法的实现,所以在那时候,@property和@synthesize通常成对出现。
  • xcode4.4之后,@property功能变得更加强大,负责set方法和get方法的声明和实现、实例变量的定义。而@synthesize功能不变。所以@property包含了@synthesize的功能,使用场景变多,而@synthesize用的场景减少。

所以,@synthesize的使用场景非常少,但是它也还是有价值的,所以Apple也没有将这个关键字删除。场景如下:

  1. 在property功能健全的时候(类中的property,且程序员没有同时自定义readwrite property的set和get的实现、readonly property的set和get实现),@synthesize的作用是更改实例变量的名字,默认是_name,可以更改为我们指定的名字;
  2. 在property功能不健全的时候(协议中定义的property,或类中的property程序员同时自定义readwrite property的set和get的实现、readonly property的set和get实现),编译器只生成了get和set的声明,@synthesize的作用定义实例变量,生成set和get的实现。
三 @dynamic

@dynamic比较简单,它也需要配合属性使用:

@implementation Student
@dynamic age;
@end

@dynamic的作用是告诉编译器,不必为我们生成set和get方法的实现以及实例变量,我们要手动实现。

结束语

至此,@property和@synthesize、@dynamic的配合使用就介绍完了。@synthesize、@dynamic是@property在某些场景下的辅助和补充。

参考官方文档:objc-apple

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值