屬性是可以說是面向對象語言中封裝的一個體現,在自定義類中設置屬性就相當於定義了一個私有變量、設置器(setter方法)以及訪問器(getter方法),其中無論是變量的定義,方法的聲明和實現都是系統自動生成的並且經過了相應地內存管理和優化,無需開發者操心。
屬性的聲明:
屬性一般定義在類的接口,或類的延展內,並且放在方法的聲明之前,成員變量的聲明之后。屬性關鍵字是@property,括號內的是屬性的屬性,然后是變量的類型和名字,屬性的定義一般分為兩種情況,一種是非對象類型的變量,如int整型,使用assign,第二種是對象類型的變量,使用retain或copy,若對象類型的變量是代理,則使用assign。
屬性的屬性包括:
1、原子性屬性:
nonatomic:非原子性,在多線程下讀寫速度較快但不安全。
atomic:原子性,在多線程下同一時間只允許一條線程進行訪問,保證數據安全。默認。
2、語義屬性:
assign:直接賦值,適用於基本數據類型和代理。
retain:賦值是使引用計數加1,適用於除代理的所有對象類型。
copy:賦值時創建一個副本,適用於除代理的所有對象類型,但會占用較多內存,謹慎使用。
3、讀寫屬性:
readwrite:可讀寫,自動生成設置器和訪問器。默認
readonly:只讀,只生成訪問器。
getter=方法名:指定訪問器的方法名。
setter=方法名:指定設置器的方法名。
點語法:
per.name=? 相當於調用屬性name的setter方法,?=per.name 或 per.name相當於調用name屬性的getter方法。
多重點語法:首先per對象有一個Student* 的對象,這個對象又帶有NSString*類型的name屬性
這種情況下是先調用per屬性stu的getter方法,再調用stu屬性name的setter方法。
屬性setter方法和getter方法的內部實現和重寫:
以@property (assign,nonatomic) int age;為例
setter方法:-(void)setAge:(int)age;
getter方法:-(int)age;
內部實現:屬性在默認情況下聲明的私有變量名為屬性名前加下划線如_age,同時在默認情況下只能重寫setter和getter的其中之一,若要重寫兩者要實現文件加上
@synthesize關鍵字,如@synthesize age = _age;
@property (assign,nonatomic) int age;
@property (retain,nonatomic) NSString *name;
@property (copy,nonatomic) NSString *sex;
設置為assign的屬性就是直接賦值,不必細說,而設置為retain或copy的屬性都是經過內存管理和優化,所用一般用於對象類型,而代理使用assign是因為被代理方本身不持有代理的所有權,所以不需要對代理的內存進行操作,直接賦值即可,而除了代理,因為對象對自己的私有變量持有所有權,所以要對私有變量進行內存管理。在setter方法中,若不對舊值所占用內存進行釋放,便會造成內存泄露,若不對新值進行retain或copy,當參數所用內存在方法外部釋放時,該屬性便會成為野指針。在getter方法中,若不進行retain或copy就進行return,當對象被釋放后便會存在野指針,若不進行autorelease便會造成內存泄露。