iOS学习笔记---oc语言第八天
屬性
能在一定程度上簡化代碼,并且增強實例變量的訪問安全性
屬性的聲明:使用@property聲明屬性 ?eg:@property NSSstring *name;相當于@interface中聲明了兩個方法
- (void)setName:(NSString *)name;
- (NSString *)name;
屬性的實現(xiàn):使用@synthesize實現(xiàn)屬性 ,eg:@synthesize name = _name;
相當于@implementation 實現(xiàn)了
- (void)setName:(NSString *)name;
- (NSString *)name;
//Person.h @interface Person : NSObject {NSString *_name; //姓名NSInteger _age; //年齡 CGFloat _score;NSString *_sex; } @property CGFloat score; //可以把相同類型的屬性放在同一行進行聲明,但是通常分開寫 @property NSString *name,*sex; //等價于下面兩行 //- (void)setName:(NSString *)name;//設(shè)置名字 //- (NSString *)name;//獲得名字 @property NSInteger age; //等價于下面兩行 //- (void)setAge:(NSInteger)age;//設(shè)置年齡 //- (NSInteger)age;//獲得年齡 @end //Person.m #import "Person.h"@implementation Person //=號前面是你聲明的屬性 //=號后面填寫setter為哪個實例變量賦值,getter獲取哪個實例變量的值 @synthesize name = _name,sex = _sex,age = _age,score =_score;//可以寫成一行,一般寫成兩行,一行可讀性差 //@synthesize age = _age;//實現(xiàn)age屬性 //@synthesize score = _score;//實現(xiàn)score屬性 //- (void)setName:(NSString *)name//設(shè)置名字 //{ // _name = name; //} //- (NSString *)name//獲得名字 //{ // return _name; //} //- (void)setAge:(NSInteger)age//設(shè)置年齡 //{ // _age = age; //} //- (NSInteger)age//獲得年齡 //{ // return _age; //} @end?屬性的屬性
第一類:讀寫性控制(readonly、readwrite、setter、getter)
如果讀寫性控制的關(guān)鍵字是readonly,是告訴編譯器,只聲明getter?方法(無setter?方法)。
例如:@property(readonly)NSString *name;
//等價于 - (NSString *)name;
如果是readwrite,告訴編譯器,既聲明setter?又聲明getter。
例如: @property(readwrite)NSString *name;
//等價于 - (NSString *)name;
- (void)setName:(NSString *)name; readwrite是讀寫性控制的默認設(shè)置。
第?類:原子性控制(nonatomic、atomic)
如果原子性控制的關(guān)鍵字是atomic。setter、getter?法在多線程訪 問下是絕對安全的,即setter、getter內(nèi)部做了多線程訪問處理。原? 性控制的默認設(shè)置是atomic
如果原子性控制的關(guān)鍵字是nonatomic。setter、getter?法內(nèi)部不會 做多線程訪問處理,僅是普通的setter、getter方法
程序開發(fā)過程中,setter、getter處都在用,如果使用atomic,
需要不斷的對setter、getter加鎖解鎖以保證線程訪問安全,會很占 ?系統(tǒng)資源,降低系統(tǒng)性能。
通常設(shè)置為nonatomic,某些屬性需要線程安全的時候,才定義為 atomic。
例如:@property (readwrite,nonatomic)NSString *name;
//等價于 – (NSString *)name;
- (void)setName:(NSString *)name;
第三類:語義設(shè)置(assign、retain、copy)
如果語義設(shè)置的關(guān)鍵字是assign。setter、getter內(nèi)部實現(xiàn)是直接賦值。
例如:@property(nonatomic,assign)NSString *name;
- (void)setName:(NSString *)name{
?? ?
? ? _name = name;
}
- (NSString *)name{
? ? return _name;
?? ?
}
//assign修飾下,setter是直接為實例變量賦值
//assign修飾下,getter是直接獲取實例變量
在如果語義設(shè)置的關(guān)鍵字是retain。setter、getter的內(nèi)部實現(xiàn)會做內(nèi)存優(yōu)化。
//retain關(guān)鍵字下,setter 是企業(yè)必考的筆試題
例如:@property(nonatomic,retain)NSString *name;
- (void)setName:(NSString *)name{
? ? if(_name != name){
?? ? ? ?
? ? ? ? [_name release];
?? ? ? ?
? ? ? ? _name = [name retain];
? ? }
?? ?
}
}
- (NSString *)name{
?? ?
? ? return [[_name retain]autorelease];
}
如果語義設(shè)置的關(guān)鍵字是copy。setter、getter的內(nèi)部實現(xiàn)也會做內(nèi)存優(yōu)化。
例如:@property(nonatomic,copy)NSString *name;
- (void)setName:(NSString *)name{
? ? if(_name != name){
?? ? ? ?
? ? ? ? [_name release];
?? ? ? ?
? ? ? ? _name = [name copy];
? ? }
?? ?
}
}
- (NSString *)name{
?? ?
? ? return [[_name retain]autorelease];
}
如果屬性是?對象類型(?比如int,float等)屬性的語義設(shè)置使用assign。
如果屬性是對象類型(?如NSStrng、NSArray等)屬性的語義設(shè)置使用retain。
如果屬性是對象類型并且想得到參數(shù)的copy,使?用copy關(guān)鍵字。
-(instancetype)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age {self = [super init];if (self) {//給實例變量賦值,使用setter ,不再單獨賦值,因為setter內(nèi)部做了內(nèi)存優(yōu)化 [self setName:name];[self setAge:age];[self setSex:sex];}return self; } //初始化以后就這樣寫點語法
凡是符合系統(tǒng)默認setter、getter書寫格式的?法都可以使?用點語 法。
例如:[person1 setName:@”zhangsan”];可以等價寫成 person1.name = @”zhangsan”;。
NSString *name = [person1 name];可以等價寫成
NSString *name = person1.name;
屬性是?對getter、setter?法,點語法是屬性的另一種調(diào)用格式
kvc
KVC(Key-Value-Coding),鍵值編碼,是?種間接訪問實例變量的方法.
key:鍵,?于標識實例變量
vlaue:實例變量對應(yīng)的值
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setValuesForKeysWithDictionary:
獲取值
valueForKey:
valueForKeyPath:
valueFoeUndefineKey:
注意事項
當key不存在的時候,會執(zhí)?setValue:forUndefinedKey:
系統(tǒng)默認實現(xiàn)是拋出一個異常
一個kvc例子,一個Person類,一個A類
//A.h中代碼 #import <Foundation/Foundation.h>@interface A : NSObject {NSString *_name; }- (void)printName; @end //A.m中代碼 #import "A.h"@implementation A -(void)printName {NSLog(@"%@ ",_name); } @end //Person.h中代碼 #import <Foundation/Foundation.h> #import "A.h" @interface Person : NSObject{NSString *_name; // NSString *_sex; NSInteger _age;A *_a; } - (void)sayHi; - (id)init; @end //Person.m中代碼 #import "Person.h" @implementation Person -(void)sayHi {NSLog(@"hello,this is %@ %ld years old ",_name,_age);[_a printName]; } //重寫方法 當key不存在的時候會調(diào)用這個方法,系統(tǒng)的默認實現(xiàn)是拋出一個異常,我們可以重寫這個方法.解決key不存在產(chǎn)生崩潰的問題 - (void)setValue:(id)value forUndefinedKey:(NSString *)key {} //當key為非對象類型,且value設(shè)置為nil的時候.會調(diào)用這個方法,系統(tǒng)默認實現(xiàn)是拋出一個異常,我們可以重寫這個方法,解決value為nil的問題 - (void)setNilValueForKey:(NSString *)key {} -(id)init {self = [super init];if (self) {_a = [[A alloc] init];}return self; } @end //main.m中代碼 #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) {Person *p1 = [[Person alloc] init];[p1 setValue:@"張三" forKey:@"name"];//kvc賦值[p1 setValue:@18 forKey:@"age"];[p1 sayHi];[p1 setValuesForKeysWithDictionary:@{@"name": @"張三",@"age": @18,@"sex": @"男"}];//比較好用 [p1 sayHi];[p1 setValue:@"哇哈哈" forKeyPath:@"a.name"];[p1 sayHi];return 0; }?
?
轉(zhuǎn)載于:https://www.cnblogs.com/limicheng/p/3821706.html
總結(jié)
以上是生活随笔為你收集整理的iOS学习笔记---oc语言第八天的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3.放弃CHAR吧,在铸成大错之前!
- 下一篇: Divide Two Integers