objective-c property


Objective C 2.0はpropertyを提供してくれました.データ・メンバーの読み書き関数を作成するプロセスを大幅に簡素化し、さらに重要なのは、データ・メンバーにアクセスするためのより簡潔で理解しやすい方法を提供することです.
まずObjective C 1について見てみましょう.x Bookクラスのヘッダファイルを宣言します.
// 
// Book.h
  
#import <Cocoa/Cocoa.h>
@interface Book : NSObject 
{ 
NSString *title;
NSNumber* numofpages; 
}
  
- (id)initWithTitle:(NSString*) booktitle andNumofpages:(NSNumber*) num;
  
- (NSString*) title; 
- (void) setTitle:(NSString*)newtitle;
  
- (NSNumber*) numofpages; 
- (void) setNumofpages:(NSNumber*)newnumofpages;
  
- (NSString*) summary;
  
@end

 Objective C 2.0 ,                property          。      :
1
2
3
4
5
6
7
8
9
10
11
//
// Book.h
 
#import <Cocoa/Cocoa.h>
 
 
@interface Book : NSObject 
{
NSString *title;
NSNumber* numofpages;
}
 
- (id)initWithTitle:(NSString*) booktitle andNumofpages:(NSNumber*) num;
 
@property (retain) NSString* title; 
@property (retain) NSNumber* numofpages;
  
@property (readonly) NSString* summary;
  
@end

データ・メンバーごとにpropertyを宣言しました.Bookクラスにsummaryというデータメンバーがいなくても、summaryというpropertyを宣言することができます.propertyを宣言する構文は、次のとおりです.
@property(パラメータ)タイプ名;
ここでのパラメータは主に3種類に分けられる:読み書き属性(readwrite/readonly)、setter語意(assign/retain/copy)、atomicity(nonatomic).
assign/retain/copyは、データ・メンバーに新しい値をどのように付与するかを決定します.summary properyを宣言する際にreadonlyを使用し、クライアントがpropertyのみを読み込むことができることを示します.atomicityのデフォルト値はatomicで、読み出し関数は原子操作です.
次に、Objective C 1について見てみましょう.x下implementationファイル:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 
// Book.m
 
#import "Book.h"
 
  
@implementation Book
  
//@synthesize title;
 
- (id)initWithTitle:(NSString*) booktitle andNumofpages:(NSNumber*) num
{ 
 self = [super init]; 
 if(nil != self) 
 { 
 [self setNumofpages:num];
 [self setTitle:booktitle]; 
 }
 return self;
}
  
- (NSString*) title
{ 
 return title; 
}
 
- (void) setTitle:(NSString*)newtitle
{ 
 [title release];
 title = [newtitle retain]; 
}
  
- (NSString*) description
{
 return title; 
}
 
 
- (NSNumber*) numofpages
{ 
 return numofpages; 
}
  
- (void) setNumofpages:(NSNumber*)newnumofpages
{
 [numofpages release]; 
 numofpages = [newnumofpages retain];
}
 
-(NSString*) summary 
{ 
 NSString* retstr = [[NSString alloc]initWithFormat:@"Title: %@, Number of pages: %@", 
title, numofpages]; 
 [retstr autorelease]; 
 return retstr; 
}
  
- (void) dealloc
{ 
 [numofpages release];
 	[title release]; 
 [super dealloc]; 
}
 
 
@end

objective c 2.0では、propertyを宣言したため、implementationファイルは次のように変更できます.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
//
/ Book.m
  
#import "Book.h"
 
 
@implementation Book
 
@synthesize title;
@synthesize numofpages;
  
- (id)initWithTitle:(NSString*) booktitle andNumofpages:(NSNumber*) num
{ 
 self = [super init]; 
 if(nil != self) 
 { 
 [self setNumofpages:num]; 
 [self setTitle:booktitle]; 
 } 
 return self; 
}
  
- (NSString*) description
{ 
 return title; 
}
  
-(NSString*) summary 
{ 
 NSString* retstr = [[NSString alloc]initWithFormat:@"Title: %@, Number of pages: %@", 
title, numofpages]; 
 [retstr autorelease]; 
 return retstr; 
}
 
- (void) dealloc
{ 
 [numofpages release]; 
 [title release]; 
 [super dealloc]; 
}
 
@end

データ・メンバーtitleとnumofpagesの読み書き関数はもう存在しません.代わりに、コンパイラが読み書き関数を提供していないときに自動的に読み書き関数を生成する2行@synthesizeが表示されます.
propertyが定義され、クライアントはbookを使用することができる.[book title]の代わりにtitleが用いられ,この構文は以前よりも直感的で簡潔である.
実装ファイルの16~17行のコードは、次のように変更できます.
1
2
self.numofpages = num; 
self.title = booktitle

上の2行のコードのselfを忘れがちな人が多いことに注意してください.この場合、マシンが生成した読み書き関数は呼び出されず、代わりに直接ポインタが値を割り当てられ、メモリの漏洩を引き起こす可能性があります.
クライアント・コードは次のとおりです.
1
2
3
4
5
6
7
8
9
10
11
12
13
1
#import <Foundation/Foundation.h> 
#import "Book.h"
  
int main (int argc, const char * argv[]) 
{ 
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
NSString* name = [[NSString alloc] initWithString:@"Harry Porter"];
NSNumber* number = [[NSNumber alloc] initWithInt:100]; 
Book *book = [[Book alloc] initWithTitle:name andNumofpages:number]; 
[number release];
[name release];	
book.title = @"Twilight"; 
book.numofpages = [NSNumber numberWithInt:200]; 
NSString* str = book.summary;
NSLog(@"summary: %@", str); 
[book release];
 
[pool drain]; 
return 0;
}