现在的位置: 首页 > 综合 > 正文

编程笔记(objective-c :声明属性)

2013年09月03日 ⁄ 综合 ⁄ 共 2856字 ⁄ 字号 评论关闭

转载请标明出处:blog.csdn.net/zhangxingping

属性的声明

    属性的声明使用关键字@property。属性的声明可以是在@interface类中的方法声明块的任何地方。@property同样也可以在protocal(协议)和category(种类)中。其通用形式如下:

@property ( attributes) type  name

    由于英文property 和attribute在汉语中都有属性的含义,为了避免混淆,暂且不对这两个词汇进行翻译。其中的attributes是用来描述名称为name的property的属性的;type表明了名称为name的property的类型,这里的类型可以是任何的objective-c的类和POD类型(关于POD参见:http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html
)类型;name表示属性的名称。

    其中,attribute可以是用逗号间隔的一组描述信息 ,这一组描述信息共同修饰后面的名称为name的property。这些描述信息可以分成如下几种:

   1.   访问方法名称相关

       缺省的Setter()方法名称为:set+属性名称 ;

       缺省的Getter()方法名称为:属性名称;

       访问方法的名称可以通过以下的方式来进行显示地指定:

       指定Setter()方法的名称:setter =方法名称;其中该方法应该是只有一个参数,且参数的类型与property的类型一致;方法的返回类型必须是void类型。

       指定Getter()方法的名称:getter = 方法名称;其中该方法的返回值应该和该 property的类型一致,并且不需要返回值。

    2.   property的可读写性

        缺省情况下,property是可读写的:readwrite,也就是说Getter和Setter方法都是存在的。还可以指定property为readonly,即该 property是只读的。此时property就不应该有setter方法。(没有看到过 writeonly的property,可能是因为这样的property没有什么实际的用处吧。)

    3.   关于setter的一些细节

下面的关键字用于描述setter方法应该如何设置property的值:

    assign

     表明setter方法只是进行简单的赋值运算。这个是缺省的。通常对于标量类型以及不属于该类的对象使用assign来进行描述。比如delegate。(标量,scalar type 是与aggregate type 相对而言的。scalar type代表的是一个简单的数值,如语言内置的数据类型基本上都是scalar type的;aggregate type代表的是相同类型的或者是不同类型的多个值,如数组,结构体,类等。)

   retain

     表明setter方法应该对新的值发送retain消息,或者说调用新值的retain方法。旧值会被发送release消息。

   copy

     表明setter方法中在进行赋值时应该进行拷贝赋值。旧值会被发送release消息。通过调用新值的copy方法来赋值给该property。这种赋值方式只适用于对象类型,并且要求该对象遵循NSCopying协议。

     上述的这些关键字是相互排斥的,也就是说同时只能使用一种。

4.   关于多线程(原子性)

可以使用nonatomic关键字来表明该property是非原子的。缺省情况下property都是原子的,这样可以在多线程环境下提供对数据的安全访问 。

另外,还有IBOutlet关键字用来表示该property是Interface  Builder的一个outlet。它不是正式的property attribute。

    来看看在之前的程序中属性name的类型为NSString*,这不是一个基本的数据类型,而name属性本身是属于Student类的对象的,因此在缺省的情况下name的setter方法将采用assign的方式进行赋值,这是不太合理的。采用retain的方式来进行赋值比较合理一些。修改上面的程序如下:

Student.h:

#import <Foundation/Foundation.h>
@interface Student : NSObject
{
@private
    NSString * name;  //学生的姓名
    float math;       //数学科目的成绩
    float english;    //英语科目的成绩 
   
}
//增加retain关键字,按照内存管理的基本原则,在dealloc的时候需要发送release消息给name 
@property (retain) NSString * name;
@property float math;
@property float english;
 
-(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish;
 
//-(NSString *)getName;
//-(float)getMath;
//-(float)getEnglish;
@end

Student.m如下:

#import "Student.h"
@implementation Student
@synthesize name;
@synthesize math;
@synthesize english;
 
- (id)init
{
    self = [super init];
    if (self)
    {
        name = nil;
        math = 0;
        english = 0;
    }
   
    return self;
}
 
-(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish
{
    self = [super init];
    if (self)
    {
        name = aName;
        math = scoreMath;
        english = scoreEnglish;
    }
   
    return self;
}
 
//-(NSString *)getName
//{
//    return name;
//}
//
//-(float)getMath
//{
//    return math;
//}
//
//-(float)getEnglish
//{
//    return english;
//}
//
//- (void)dealloc
//{
//    [super dealloc];
//}
 
-(void) dealloc
{
    [name release];  //销毁对象的时候发送release消息给name。 
    [super dealloc];
}
 
@end

main.m保持不变。此时编译,发现之前出现的编译警告消失了。程序输出结果如下:

Name:Tony

Math:99.000000

Math:89.980003

结果正确。

抱歉!评论已关闭.