標籤:
------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------
編譯器特性@property和@synthesize
1、@property
@property可以自動產生某個成員變數的setter和getter聲明。
建立一個項目,添加Person類。
Person.h
//// Person.h// zijia//// Created by zou on 5/10/15.// Copyright (c) 2015 __MyCompanyName__. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age; double _height; }
@property int age;- (void)setHeight:(double)height;- (double)height;@end
當編譯器遇到@property 會自動延伸對應的setter和getter聲明,這裡@property int age會自動延伸成:
- (void)setAge:(int)age;- (int)age;
這裡可以驗證一下,看一下能不能在main.m中調用set和get方法。
main.m
#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]){ @autoreleasepool { Person *p = [Person new]; [p setAge : 10]; int a = [p age]; // int a = [p age]; NSLog(@"age is %d",a); } return 0;}
有了聲明還應該有實現
Person.m
#import "Person.h"@implementation Person- (void)setAge:(int)age{ _age = age; }- (int)age{ return _age;}- (void)setHeight:(double)height{ _height = height;}- (double)height{ return _height;}@end
這裡對象p調用了set和get方法,看編譯能不能通過。
列印結果:
這裡證明@property確實產生了成員變數的setter和getter聲明。
所以這裡成員變數_height的setter和getter聲明也可寫成@property double height;
@property double height;//- (void)setHeight:(double)height;//- (double)height;@end
二、@synthesize
@synthesize可以自動產生成員變數setter和getter實現部分,並且會訪問“_成員變數”這個成員變數。
Person.m
#import "Person.h"@implementation Person@synthesize age=_age;@synthesize height=_height;
- (void)test
{
NSLog(@"age=%d,_age=%d",age,_age);
}@end
@synthesize age = _age; 等號右邊的_age,表示將來set方法設定的值將會賦值給成員變數_age,這裡為了驗證可以添加一個成員變數int age;
Person.h
#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age; int age; double _height; }@property int age;@property double height;- (void)test;@end
如果在Person.m中寫的是@synthesize age = age,那麼set方法將來就會把值賦給成員變數age,這裡可以寫個test方法驗證一下。
main.m
#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]){ @autoreleasepool { Person *p = [Person new]; [p setAge : 10]; [p test]; } return 0;}
這裡編譯運行一下:
通過列印結果我們發現age的值沒有改變,還是預設值0,而_age的值變成了10,這裡我們把Person.m裡面的@synthesize age=_age,寫成@synthesize age=age,重新列印一下結果發現:
age的值變成了10,而_age值為0,這說明setter方法究竟改變那個成員變數,取決於@synthesize 等號後面的變數是什麼。
這裡發現使用編譯器特性@property和@synthesize可以避免寫很多重複的代碼,這裡還可以更精簡。
新添加一個Dog類。
Dog.h
#import <Foundation/Foundation.h>@interface Dog : NSObject@property int age;@end
這裡都不用寫成員變數,Dog.m裡面也不用寫實現的代碼,@property int age這行代碼做了三件事情:
第一,產生getter和setter的聲明;
第二,產生了一個_age的成員變數;
第三;產生了getter和setter的實現;
這裡可以驗證一下:
main.m
#import <Foundation/Foundation.h>#import "Person.h"#import "Dog.h"int main(int argc, const char * argv[]){ @autoreleasepool { Person *p = [Person new]; p.age = 5; NSLog(@"age=%d",p.age); } return 0;}
列印一下結果:
這裡驗證了之前的說法。這裡需要注意的是age預設是私人成員變數,子類是不能訪問的,如果想讓子類也能訪問的話,需要寫明成員變數。
#import <Foundation/Foundation.h>@interface Dog : NSObject{ int _age;}@property int age;@end
@property age; 預設會訪問age這個成員變數,如果沒有age就會自動產生@private類型的age。
@synthesize age; 預設會訪問age這個成員變數,如果沒有age就會自動產生@private類型的age。
自從Xcode 4.x之後,@property功能就涵蓋了@synthesize的功能,@synthesize就可以省略不寫。
如果手動實現setter方法,編譯器就會自動產生getter方法和帶底線的成員變數。
如果手動實現getter方法,編譯器就會自動產生setter方法和帶底線的成員變數。
如果手動實現setter和getter方法,編譯器就不會產生getter和setter方法,也不會產生帶底線的成員變數。
黑馬程式員---Objective-C基礎學習---編譯器特性@property和@synthesize