Objective-C之@property和@synthesize

http://mobile.51cto.com/iphone-392353.htm

今天要说的内容是Objective-C 中的 @property和@synthesize。在这之前先讲讲访问器(Accessor),也就是我们所知道的setter和getter方法。 《Cocoa Design Patterns》中的将它归类为基础模式中的一种。访问器是很重要的技术,用来访问和设置对象的实例变量(不是指对象本身,而是对象中的属性)。有时候 可能需要用不同的方式或者通过计算等方式来获取或设置实例变量,访问器给了我们很大的灵活性。在Cocoa中访问器有很多的优点:

  • 实现灵活性。 可以在访问器中改变并实现不同的实例变量访问方式而不影响其他代码。
  • 可维护性。通过访问器对实例变量的更改易于维护。
  • 内存管理。访问器方法提供了简单的方法去遵守Cocoa的约定把内存管理代码隔离在少部分代码中。
  • 支持KVC和KVO。 KVC和KVO是很强大的技术。但是它们依赖于正确命名访问器。

下面这段代码简单的实现了一个访问器(setter和getter):

 
 
  1. //setter 
  2.     -(void)setStuName:(NSString *)stuName 
  3.       {  //_stuName 是实例变量 
  4.          if (_stuName != stuName) 
  5.          { 
  6.             [_stuName release]; 
  7.              _stuName = [stuName copy]; 
  8.          } 
  9.       } 
  10.     //getter 
  11.       -(NSString *)stuName 
  12.       { 
  13.          return _stuName; 
  14.       } 

上面代码中的setter中还涉及到一定的内存管理,既然这个技术这么重要,那么有没有一种更方便的方法去做呢?答案就是@property和@synthesize。它们是Objective-C 2.0加入的指令,前者用于声明,后者用于合成访问器,结合使用就可以自动生成访问器了。

下面这段代码使用@property和@synthesize:

 
 
  1. @interface Student : NSObject 
  2.     @property (nonatomic, copy) NSString *stuName; 
  3.     @end      
  4.     @implementation Student 
  5.     @synthesize stuName = _stuName; 
  6.     @end

这段代码的效果跟上面代码的效果是一样的,是不是很方便呢?

使用@property和@synthesize很方便,但又给我们带来了很多疑问比如在上面的代码中又出现了nonatomic和copy,是什么意 思?在@property中还有其他几个关键字,它们都是有特殊作用的,我把它们分为三类分别是:原子性,访问器控制,内存管理。

原子性

atomic(默认):atomic意为操作是原子的,意味着只有一个线程访问实例变量。atomic是线程安全的至少在当前的访器上我是安全的。它是一个默认的,但是很少使用。它的比较慢,这跟ARM平台和内部锁机制有关。

nonatomic: nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。它的速度比atomic快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。

访问器控制

readwrite(默认):readwrite是默认的,表示同时拥有setter和getter。

readonly: readonly 表示只有getter没有setter。

有时候为了语意更明确可能需要自定义访问器的名字:

 
 
  1. @property (nonatomic, setter = mySetter:,getter = myGetter ) NSString *name; 

最常见的是BOOL类型,比如标识View是否隐藏的属性hidden。可以这样声明

 
 
  1. @property (nonatomic,getter = isHidden ) BOOL hidden; 

要注意修改setter或者getter的名字是存在副作用的,可能会使KVC和KVO无法正常工作。

内存管理

retain:使用了retain意味着实例变量要获取传入参数的所有权。具体表现在setter中对实例变量先release然后将参数 retain之后传给它。下面这段代码展示了retain类似的行为:

 
 
  1. -(void)setStuName:(NSString *)stuName 
  2.       { 
  3.          if (_stuName != stuName) 
  4.          { 
  5.             [_stuName release]; 
  6.              _stuName = [stuName retain]; 
  7.          } 
  8.       } 

assign(默认):用于值类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate。

strong:是在ARC伴随IOS引入的时候引入的关键字是retain的一个可选的替代。表示实例变量对传入的参数要有所有权关系即强引用。strong跟retain的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。

weak: weak跟assign的效果相似,不同的是weak在对象被回收之后自动设置为nil。而且weak智能用在iOS 5或以后的版本,对于之前的版本,使用unsafe_unretained。

unsafe_unretained:weak的低版本替代。  

copy:copy是为是实例变量保留一个自己的副本。

现在明白了@property是怎么回事了,但是@synthesize是怎么回事,看看之前的第一段代码:

 
 
  1. @synthesize stuName = _stuName; 

这里的stuName = _stuName是什么意思?stuName是propertyName跟@property声明的名字一样。而后面的_stuName 是实例变量名。生成的访问器就是来访问的 _stuName的。代码的样子就和最开始那setter和getter代码所描述的一样。

注意一个问题,我们并没有声明_stuName这个变量,这是编译器自动帮我们创建的。 如果这段指令我换个写法:@synthesize stuName = a;   并且我们没有在interface里面声明这个变量,那么会自动创建一个变量a。

如果这里写成这样:

 
 
  1. <em>@synthesize stuName; 
  2.     //等同于 
  3.     @synthesize stuName = stuName;</em> 

在Xcode4.4中,Xcode添加的一些新的编译特性。其中一个就是默认合成(Default Synthesis)。默认合成就不再需要显示的使用@synthesize指令了,这很方便但是要注意的是,默认合成遵守的约定,这里的也就是命名规则是propertyName = _propertyName。 

下面一段代码帮助理解:

 
 
  1. //对于下面的@propety 
  2.     @property (nonatomic, copy) NSString *stuName; 
  3.     //默认合成的规则是这样: 
  4.     @synthesize stuName = _stuName; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值