@property(nonatomic,strong)NSString *people;
則在類內能夠直接調用成員變量_people。objective-c
@interface People : NSObject /* 聲明方法 - 、+ 是方法的類型,(-表明對象方法(用對象名來調用),+表明類方法(用類名來調用)), (加號方法和減號方法能夠互相調用,可是須要類名和實例化變量,加號方法不能調用成員變量。) */ - (void)report; + (void)report; @end
在對象方法中調用類方法,和在類方法中調用對象方法安全
/* .m文件對方法的實現 */ - (void)report { NSLog(@"- 號: report"); [People report1]; } + (void)report1 { NSLog(@"+ 號:report1"); [[People alloc] report]; }
//初始化方法 - (id)init; /* id類型是萬能類型,能夠返回各類類型對象 */ -(instancetype)init; /* instancetype表明當前類的類型 */
對於選擇哪一個,在初始化方法中都行,對於其餘的一些方法,填id會致使錯誤,通常填寫instancetype。app
以下代碼框架
@interface NSArray + (id) creatAnArray; @end
當咱們用以下方式初始化NSArray時:函數
[NSArray creatAnArray];
性能
獲得的返回類型將和方法聲明的返回類型同樣,是id;學習
但當咱們將id改成instancetype時:atom
@interface NSArray + (instancetype) creatAnArray; @end
再用剛一樣的方式初始化時:指針
[NSArray creatAnArray];
code
獲得的返回類型將會和方法所在類的類型相同,是NSArray*;
instancetype在編譯的時候能夠判斷對象的真實類型
若是是在之前, init的返回值是id,那麼將init返回的對象地址賦值給其它對象是不會報錯的
id能夠用來定義變量, 能夠做爲返回值, 能夠做爲形參
instancetype只能用於做爲返回值,例如:
//err,expected a type
{
//do something
}
就是錯的,應該寫成:
{
//do something
}
**參考自[iOS instancetype 和 id 區別詳解](https://juejin.im/entry/588022572f301e00697c8756)** ## 封裝 - 修飾符的問題
@interface MyClass : NSObject
{
//成員變量訪問修飾符的問題 //默認 - 受保護 //公有 - 在類內類外均可以使用 @public int _classInt; /*聲明爲公有成員類型,則在類外也能夠被調用,可是要用指向(->)調用*/ //私有 - 在類內可使用,類外沒法調用而且不能被繼承 @private //受保護 - 在類內可使用,類外沒法調用而且能夠被繼承 @protected //框架權限 - 在框架內至關於受保護,在框架外至關於私有 @package
}
@property(nonatomic,strong)NSString *className;
//方法是沒有訪問修飾符的同C語言同樣
@end
## 繼承 - OC中沒有多繼承,要實現多繼承要經過協議來實現。 - 父類中的私有成員變量是沒法繼承使用的,而若是子類繼承了父類的方法,方法中有隊私有變量的操做以及打印,那咱們是能夠看到的,可是咱們不能夠在子類中直接調用私有變量。 - 若是父類中的方法沒有寫聲明則子類沒法繼承父類中對應的方法。 ## 多態 - OC中不支持方法的重載 ## 註釋 - 使用 /\*\* 文本 **/ 的註釋格式(快捷鍵cmd+alt+/)能夠對方法等進行快速註釋。 ## 修飾符 在蘋果引入ARC以後,修飾符有所增長 ### 存取類型 1. 任何屬性均可以聲明爲readwrite或readonly,且默認設置爲readwrite 2. readwrite:程序自動建立setter/getter方法。 3. readonly:程序之建立getter方法。 4. 自定義setter/getter方法 : @propery(setter=setId,getter=getId) int id; ### 原子性 1. atomic:生成的setter/getter操做爲原子性的操做,執行性能較低(系統默認)。 2. noatomic:生成的setter/getter操做爲非原子性的操做,執行性能較高。通常推薦手動設置爲該屬性。 ### 生命週期 #### MRC 1. assign: 簡單賦值,不更改引用計數。通常用於基礎類型的數據(NSInteger)和C語言類型數(int,float,double,char,bool)。是MRC模式下的默認值。 2. copy: 會拷貝傳入的對象(即建立一個引用計數爲1的新對象,可是內容與傳入對象相同),並把新對象賦值給實例變量。經常使用與NSString,NSArray,NSDictionary,NSSet等。 3. retain: 釋放舊對象,並使傳入的新對象引用計數+1。此屬性只能用於NSObject及其子類,而不能用於Core Foundation(由於其沒有使用引用計數,須要另外使用CFRetain和CFRelease愛進行CF的內存管理)。 #### ARC ARC中加入如下修飾符 1. strong: 強引用,相似於retain。要求保留傳入的對象,並放棄原有對象。一個對象只要被至少一個強引用指向,則其不會被釋放,而當沒有強引用指向時則會被釋放。在ARC下是對象類型的默認值。 2. weak: 弱引用,要求不保留傳入的屬性(既不會使傳入的對象引用計數+1)。相似於assign,但與assign不一樣的是,當它們指向的對象被釋放後,weak會被自動置爲nil,而assign則不會,因此assign會致使「野指針」的出現,weak能夠避免懸空指針。 3. unsafe_unretained: 其實質等同於assign。與weak的區別就是指向的對象若是被釋放,其不會被置爲nil,而致使懸空指針的出現。它是ARC模式下非對象屬性的默認值。 #### 屬性的默認值 - MRC:(atomic, readwrite, assign) - ARC下對象類型屬性:(atomic, readwrite, strong) - ARC下非對象類型:(atomic, readwrite, unsafe_unretained) ### 關於copy和strong - **使用`copy`修飾immutable類型,使用`strong`修飾mutable類型** 引用一下一句話: > For attributes whose type is an immutable value class that conforms > > to the `NSCopying` protocol, you almost always should specify `copy` > > in your `@property` declaration. Specifying retain is something you > > almost never want in such a situation. 舉個例子:
@interface UserInfo : NSObject <NSCopying>
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@end
//main 函數中
NSMutableString *mutableFirstName = [NSMutableString stringWithFormat:@"張"];
NSMutableString *mutableLastName = [NSMutableString stringWithFormat:@"全蛋"];
UserInfo *my = [[UserInfo alloc] init];
my.firstName = mutableFirstName;
my.lastName = mutableLastName;
NSLog(@"全名:%@%@", my.firstName, my.lastName);
// print: 全名:張全蛋
// 改mutableFirstName 張 爲 李
[mutableFirstName deleteCharactersInRange:NSMakeRange(0, 1)];
[mutableFirstName appendString:@"李"];
// 改mutableLastName 全蛋 爲 沒蛋
[mutableLastName appendString:@"沒蛋"];
NSLog(@"全名:%@%@", my.firstName, my.lastName);
// print: 全名:張沒蛋
對於immutable對象類型屬性,假設該類型存在mutable版本,若使用`strong`修飾該屬性,則將會是不安全的。好比在上述例子中,`my.firstName`被`copy`修飾,而`my.lastName`被`strong`修飾,當把mutable類型賦給了immutable類型(即`NSMutableString`賦給`NSString`),以後又修改mutable類型變量的值(將張改成李,全蛋改成沒蛋),`copy`修飾的`firstName`不會改變,而`strong`修飾的`lastName`會隨之改變。這是不但願發生的。 對於二者的setter方法的定義以下:
}
}
若是去掉copy,寫成下面這個樣子,則copy的好處將不復存在。
}
- 不是全部遵循`NSCopying`類型屬性都應該使用`copy`修飾,而是對於`NSString`、`NSDictionary`等屬性才須要使用`copy`修飾,由於它們存在mutable版本,在爲屬性賦值時,右值極可能是它們的mutable類型對象,若使用`strong`修飾則會帶來不穩定因子;另一個方面,若是屬性類型不存在對應的mutable版本,則徹底不用擔憂這點,反正你也沒法在外部修改它,不穩定因子天然不存在了。(參考[Objective-C copy那些事兒](http://zhangbuhuai.com/copy-in-objective-c/)) - mutable屬性類型不能用`copy`修飾,被修飾符`copy`修飾的屬性,默認的setter賦值方式是`_iVar = [var copy];`而`copy`方法返回的是immutable類型,將immutable對象賦值給mutable類型指針顯然是不對的。 ## 內存管理法則