標籤:
一、property
合成存取器:
@property的格式:
1 @property (修飾列表) 變數類型 變數名;
Xcode4.4之前:
@property使編譯器自定產生set/get方法聲明。
@synthesize自動產生set/get方法的實現
@synthesize還會自動產生私人成員變數
Xcode4.4以後:
不用再寫@synthesize,編譯器通過@property就能給我們產生set/get方法的聲明和實現,預設產生成員變數:_propertyName
用@property產生的成員變數是私人的。
當我們想改變預設的成員變數名時,@synthesize age = newName;‘
如果子類想訪問父類的成員變數,
1、通過set/get方法
2、顯示的聲明成員變數
**進入正題**
首先聲明:
category和protocol可以添加方法
category 和 protocol中可以添加@property 關鍵字
二、關於protocol中的property
在protocol中添加property時,其實就是聲明了 getter 和 setter 方法,在實現這個protocol協議的類中,我們要自己手動添加執行個體變數,並且需要實現setter/getter方法
虛擬碼:
main.m
1 Student *student = [[Student alloc] init];2 3 student.name = @"彭爸爸";4 5 NSLog(@"%@", student.name);6
person.h
設定協議,與其中的property
1 // 2 // Person.h 3 // 類別 和 協議 4 // 5 // Created by ma c on 16/5/19. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h>10 11 @protocol personDelegate <NSObject>12 13 @property (nonatomic, copy) NSString *name;14 15 @end16 17 @interface Person : NSObject18 19 @end
student.h
產生成員變數,_name
1 // 2 // PersonSon.h 3 // 類別 和 協議 4 // 5 // Created by ma c on 16/5/19. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h>10 #import "Person.h"11 12 @interface Student : NSObject <personDelegate>13 {14 //***聲明成員變數***15 NSString *_name;16 }17 18 19 @end
student.m
這裡寫了兩種方法,一種是自動實現setter/gerter,一種為手動setter/gerter
1 // 2 // PersonSon.m 3 // 類別 和 協議 4 // 5 // Created by ma c on 16/5/19. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import "Student.h"10 11 @implementation Student12 13 //------------------自動----------------------//14 //@synthesize 15 //16 //編譯器期間,讓編譯器自動產生getter/setter方法。17 //18 //當有自訂的存或取方法時,自訂會屏蔽自動產生該方法19 20 //自動產生setter/getter方法21 22 //@synthesize name;23 24 25 26 //------------------手動----------------------//27 28 //@dynamic29 //30 //告訴編譯器,不自動產生getter/setter方法,避免編譯期間產生警告31 //32 //然後由自己實現存取方法33 34 //實現Person中定義的屬性name的set方法35 - (void)setName:(NSString *)name {36 _name = name;37 38 }39 40 //實現Person中定義的屬性name的get方法41 - (NSString *)name {42 return _name;43 }44 45 @end
列印Log日誌為:
說明成功實現property的準系統,並可以實現賦值與取值操作
三、category中的property
在category中添加property時, 在@implentation添加 getter 和 setter方法時, 由於category不能添加執行個體變數
1)使用臨時全域變數來替代成員變數
首先聲明:Person沒有name屬性
main.m
匯入標頭檔:
#import "Person+Extension.h"
1 Person *person = [[Person alloc] init];2 3 person.name = @"peng";4 5 NSLog(@"%@", person.name);
Person+Extension.h
1 // 2 // Person+Extension.h 3 // 類別 和 協議 4 // 5 // Created by ma c on 16/5/19. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import "Person.h"10 11 @interface Person (Extension)12 13 @property (nonatomic, strong) NSString *name;14 15 @end
Person+Extension.m
1 // 2 // Person+Extension.m 3 // 類別 和 協議 4 // 5 // Created by ma c on 16/5/19. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import "Person+Extension.h"10 #import <objc/runtime.h>11 12 //***臨時變數***13 static NSString *_name;14 15 @implementation Person (Extension)16 17 - (void)setName:(NSString *)name {18 _name = name;19 }20 21 - (NSString *)name {22 return _name;23 }24 @end
2)使用runtime 關聯對象 實現成員變數
除了Person+Extension.m 其他與 第一種方法一致
runtime Person+Extension.m
1 @implementation Person (Extension) 2 3 - (void)setName:(NSString *)name{ 4 objc_setAssociatedObject(self,@selector(name),name,OBJC_ASSOCIATION_RETAIN_NONATOMIC); 5 } 6 7 - (NSString *)name{ 8 9 NSString *n = objc_getAssociatedObject(self, @selector(name));10 return n;11 }
兩種方式列印Log日誌相同,同時為:
iOS Category 和 Protocol 中的 Property 你們真的會了嗎?