Objective-C 学习笔记(四) 已声明的特性 - 推荐

      在面向对象里面,讲究开放-封闭原则,类的成员函数不能被其他类直接访问,通常需要为每个需要访问的变量编写get和set函数,这是个繁琐的事情。Objective-C的这个特性解决了这个问题。

 

      下面通过例子来详解:

 

声明如下:

@interface TestCoop : NSObject {
    int iYear;
    int iMonth;
    int iDay;
}

@property int iYear; //等同于下面被注释的两句
//- (void) setIYear: (int) iYear;

//-(int) iYear;


- (void) primalSetData: (int)iYear :(int)iMonth :(int)iDay;
- (void) setData: (int)Year iMonth:(int)iMonth iDay:(int)iDay;
- (void) displayDateInfo;

@end

 

 

@interface TestAddWeather : TestCoop{
    NSString *pstrWeather;
}

@property  (copy) NSString *pstrWeather; //等同于下面被注释的两句

//- (void) setPstrWeather: (NSString *) pstrWeather;
//- (NSString *) pstrWeather;


@end

 

 

定义如下:

@implementation TestCoop
- (void) displayDateInfo{
    NSLog(@"Today is: %d.%d.%d/n", iYear, iMonth, iDay);
}

@synthesize iYear; //等同于下面被注释掉的2个函数
//- (void) setIYear: (int) year{
//    iYear = year;
//}
//
//- (int) iYear{
//    return iYear;
//}

- (void) primalSetData: (int)year :(int)month :(int)day{
    iYear = year;
    iMonth = month;
    iDay = day;   
}

- (void) setData: (int)year iMonth:(int)month iDay:(int)day{
    iYear = year;
    iMonth = month;
    iDay = day;
    ;
}

@end


@implementation TestAddWeather
@synthesize pstrWeather; //等同于下面被注释掉的2个函数
//- (void) setWeather: (NSString *) pWeather{
//    [pstrWeather release];
//    pstrWeather = [pWeather copy];
//}

//- (NSString * pWeather) pstrWeather{
//    return pstrWeather;
//}


- (void) displayDateInfo{
    NSLog(@"Today is: %d.%d.%d,weather: %@/n", iYear, iMonth, iDay, pstrWeather);
}
@end

 

测试代码:

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // insert code here...
    //NSLog(@"%d-,%s %@/n", 12, "hel123lo", @"123");
    TestCoop *ptest = [[TestCoop alloc] init];
    [ptest primalSetData :2009 :03 :05];
    [ptest displayDateInfo];
    [ptest setData:2010 iMonth:06 iDay:06];
    [ptest displayDateInfo];
    //[ptest setYear:1987];
    NSLog(@"now year is %d", [ptest iYear]);
    [ptest setIYear:1981];
    [ptest displayDateInfo];
    [ptest release];
    TestAddWeather *ptestweather = [[TestAddWeather alloc] init];
    [ptestweather setData:2010 iMonth:03 iDay:05];
    //[ptestweather setWeather:@"Rainy"];
    [ptestweather setPstrWeather:@"Rainy"];
    [ptestweather displayDateInfo];
    //[ptestweather setWeather:@"Cloudy"];
    //[ptestweather setPstrWeather:@"Cloudy"];
    ptestweather.pstrWeather = @"Cloudy";
    [ptestweather displayDateInfo];
   
    [ptestweather release];
    [pool drain];
    return 0;
}

 

声明部分,可以用@property int iYear;来代替原来的set和get函数的声明,

定义部分,可以用@synthesize iYear;来代替原来set和get函数的定义,

这两个通常要配套使用,如果只写其中一个,另外一部分还是要自己补全的。

 

在@property 后面,还可以加一些关键字来描述该关键字。

第一类:

Writability

These attributes specify whether or not a property has an associated set accessor. They are mutually exclusive.

readwrite

Indicates that the property should be treated as read/write. This is the default.

Both a getter and setter method will be required in the @implementation . If you use @synthesize in the implementation block, the getter and setter methods are synthesized.

readonly

Indicates that the property is read-only.

If you specify readonly , only a getter method is required in the @implementation . If you use @synthesize in the implementation block, only the getter method is synthesized. Moreover, if you attempt to assign a value using the dot syntax, you get a compiler error.


 

 

标志只读或者可读写,默认是可读写的,通常在只读的时候才需要加标志

比如:@property (readonly ) int iYear;

 

第二类:

Setter Semantics

These attributes specify the semantics of a set accessor. They are mutually exclusive.

assign

Specifies that the setter uses simple assignment. This is the default.

You typically use this attribute for scalar types such as NSInteger and CGRect , or (in a reference-counted environment) for objects you don’t own such as delegates.

retain and assign are effectively the same in a garbage-collected environment.

retain

Specifies that retain should be invoked on the object upon assignment. (The default is assign .)

The previous value is sent a release message.


copy

Specifies that a copy of the object should be used for assignment. (The default is assign .)

The previous value is sent a release message.

The copy is made by invoking the copy method. This attribute is valid only for object types, which must implement the NSCopying protocol . For further discussion, see “Copy.”

 

这一类是表示设置参数时候的方式,默认,拷贝,保留等

copy就是拷贝,可以参考我们上面的代码

retain就是保留,仅维持一个计数

assign是默认的,不需要设置,通常设置int,float之类的变量

 

 

第三类:

Atomicity

This attribute specifies that accessor methods are not atomic. (There is no keyword to denote atomic.)
nonatomic

nonatomic

Specifies that accessors are non-atomic. By default, accessors are atomic.

Properties are atomic by default so that synthesized accessors provide robust access to properties in a multi-threaded environment—that is, the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently. For more details, see “Performance and Threading.”

If you do not specify nonatomic, then in a reference counted environment a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value—the implementation will be similar to the following:

[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

If you specify nonatomic, then a synthesized accessor for an object property simply returns the value directly.

 

 

 

如果有一种以上参数,则使用逗号分隔,

比如:

@property(copy, readwrite) NSString *value;

我个人感觉这个特性是相当的好用啊,不用都对不住他。

 

Objective-C 2.0还提供了点表达式来方便C++的变量访问方式,点表达式如果出现在等号(=)左边,则属性set方法被调用,如果出现在右边,则get方法被调用。

比如:在代码示例中,以下2句是等效的:

    [ptestweather setPstrWeather:@"Cloudy"];
    ptestweather.pstrWeather = @"Cloudy";

 

posted @ 2010-08-05 14:16  MXi4oyu  阅读(108)  评论(0编辑  收藏  举报