你對@synthesize混淆了嗎?

從來吃不胖發表於2018-09-05

簡單談談 @synthesize

@synthesize 是編譯器自動生成 setter/getter 方法的實現(實現實現實現很重要)的關鍵詞。當前開發中使用了 @property 後,會在 .m 中自動生成 @synthesize 屬性名 = _屬性名,而不是 @property 本身幫我們生成 setter/getter 方法,@property 本身只是生成 setter/getter 方法的宣告(宣告宣告宣告很重要)。

@synthesize 寫出來的程式碼可能會長這樣:

  1. @synthesize boy;

  2. @synthesize boy = boy;

  3. @synthesize boy = _boy;

  4. (girl是事先宣告好的一個變數)

 @implementation ViewController {
     NSObject *girl;
 }
 @synthesize boy = girl;
複製程式碼
  1. @synthesize boy = noDeclaredVar;(noDeclaredVar是指沒有宣告過,隨便打出來的)

上述5個程式碼都是能夠正常使用的。看著有點繞,新手可能看不懂這到底是幹嘛的。

簡單解釋下,@synthesize boy 預設等於 @synthesize boy = boy;。那麼只要理解一種:@synthesize xx = yy; 即可。這個“等式”表明“之前用@property (nonatomic, strong) NSObject *boy; 宣告的這個“屬性”在 setter/getter 方法中實際使用的例項變數是 yy,如果 yy 沒有手動宣告,那麼會自動宣告為一個例項變數。

補充一點:xx 必須是用 @property 宣告過的。

我們對照著上面的5個關鍵字程式碼看看。

  1. @property 宣告的boy,在 setter/getter 方法中使用 NSObject *boy; 這個例項變數來賦值與返回。
  2. 同1。
  3. @property 宣告的boy,在 setter/getter 方法中使用 NSObject * _boy; 這個例項變數來賦值與返回。
  4. @property 宣告的boy,在 setter/getter 方法中使用 NSObject *girl; 這個例項變數來賦值與返回。
  5. @property 宣告的boy,在 setter/getter 方法中使用 NSObject * noDeclaredVar; 這個例項變數來賦值與返回。

@synthesize 使用指定的屬性實踐

@interface ViewController ()

@property (nonatomic, copy) NSObject *boy;

@end

@implementation ViewController {
	NSObject *boy;
	NSObject *girl;
}
@synthesize boy = girl;

- (void)viewDidLoad {
	[super viewDidLoad];

	self.boy = [[NSObject alloc] init];
	NSLog(@"請問那個孩子已經出生了?boy : %@  girl : %@",boy, girl);
}

@end
複製程式碼
  1. @implementation 中宣告的成員屬性 NSObject *boy@property 宣告的boy是否是同一個物件?還存不存在 _boy 這個例項變數?

    不是,@synthesize已經指定了 girl 作為 setter/getter 方法裡使用的例項變數,不再自動生成 _boy 這個例項變數了。

  2. @synthesize boy = girl; 到底是把 boy 變成了 girl ,還是把 girl 變成了boy?

    沒有變來變去,因為壓根不存在 _boy 了。是把 boy 的 setter 方法 - (void)setBoy:(NSObject *)boy 的實現改成了 girl = boy ,即把 _boygirl 替代。已經不存在 _boy 這個成員變數了。

相關文章