8-访问成员变量和属性

最后更新于:2022-04-01 00:17:11

#### 访问成员变量 从面向对象的封装角度考虑问题, 要想访问类中的成员变量, 是要通过方法访问的,  成员变量前面要有作用域限定符(protected, public, private) ,  这些存取权限修饰符我们将在后面介绍。  成员变量的访问, 是通过读取方法(getter) 和设定方法(setter)。 访问成员属性: 可以使用点运算符.,或发送消息[] 以上一节中的音乐类为例子: ~~~ Song.h文件 @interface Song : NSObject { NSString *title; NSString *artist; long int duration; } //操作方法 - (void)start; - (void)stop; - (void)seek:(long int)time; //访问成员变量方法 - (NSString *)title;  - (void) setTitle:(NSString *) newTitle; - (NSString *)artist;  - (void) setArtist:(NSString *) newArtist; - (long int)duration;  - (void) setDuration:(long int) newDuration; @end Song.m文件 @implementation Song - (void)start { //开始播放 } - (void)stop { //停止播放 } - (void)seek:(long int)time { //跳过时间 } //访问成员变量方法 - (NSString *)title { return title; } - (void) setTitle:(NSString *) newTitle { title = newTitle; } - (NSString *)artist { return artist; } - (void) setArtist:(NSString *) newArtist { artist = newArtist; } - (long int)duration { return duration; } - (void) setDuration:(long int) newDuration { duration = newDuration; } @end ~~~ #### 小结 采用了封装之后就可以通过存取方法访问属性,  例如[mySong title] 是取得title成员变量内容。  如果不考虑封装的问题, 单从技术上讲Objective-C, 可以直接通过对象访问成员变量的,  访问操作符是“->” ,  例如: mySong->title, 也可以取得title成员变量的内容。 需要指出的是,也可以对自定义的方法使用点运算符,不仅仅是使用在synthesize上(即属性)。 注意: 点运算符和发消息都是可以的,但是,点运算符通常使用在属性上,用于设置或取得实例变量的值。 方法在Apple的文档中被标记为任务(Task),任务通常不是由点运算符执行的, 而是使用传统的方括号形式的消息表达式作为首选的语法。 另外,使用合成(synthesize)的存取方法,属性名称的前面不要以new、alloc、copy和init这些此开头。 这与编译器的一些假定有关,因为编译器会合成相应的方法。 #### 属性 对于成员变量的访问, 要通过读取方法(getter) 和设定方法(setter) 。  在实现部分也要实现这些读取方法和设定方法,  为了简化这些琐碎编码Objective-C2.0提出属性的概念,  使用 @property关键字在接口部分定义属性,  在实现部分使用 @synthesize关键字在组装和合成这些属性。 这种可自动生成设值方法和取值方法(统称为存取方法)。 具体步骤如下: 1)在接口部分中使用@property指令标识属性。 ~~~ @interface Fraction : NSObject @property int numerator, denominator; @end ~~~ 2)在实现部分使用@synthesize指令即可。 ~~~ @inplementation Fraction @synthesize numerator, denominator; @end ~~~ 再次实现头文件如下: ~~~ @interface Song : NSObject { NSString *title; NSString *artist; long int duration; } //操作方法 - (void)start; - (void)stop; - (void)seek:(long int)time; //访问成员变量方法 @property(copy,readwrite) NSString *title; @property(nonatomic,retain) NSString *artist; @property(readonly) long int duration; @end ~~~ #### 代码说明: 声明property的语法为: @property (参数) 类型 名字; ,  这里的“参数” 主要分为3大类:  •读写属性(readwrite/readonly) ;  •内存管理(assign/retain/copy) , 这些内存管理的参数, 我们将在内存管理小节部分介绍;  •原子性atomicity(nonatomic) , 是关系线程线程安全的, atomicity是原子性的线程安全的, 但是会影响性能。  如果确定不考虑线程安全问题可以使用 nonatomic。 > 注意: > 如果使用了@property指令,就不需要在实现部分声明相应的实例变量。 通常,如果有称为x的属性,那么在实现部分包括以下行会导致编译器自动实现一个取值方法x和一个设置方法setX: @synthesize x; 因为生成的存取方法是高效的,并且在使用多个核心的多台机器上,使用多线程时也可正常运行。 (这里的说法呢,就是说线程安全的) 实现.m文件如下: ~~~ @implementation Song @synthesize title; @synthesize artist; @synthesize duration; - (void)start { //开始播放 } - (void)stop { //停止播放 } - (void)seek:(long int)time { //跳过时间 } @end ~~~
';