1,循環(huán)引用
@interface ClassB ()
@property (nonatomic, strong) ClassA *classA;
@end
如代碼,classA 是ClassB的一個(gè)屬性,就是說(shuō)ClassB擁有(也可說(shuō)引用)classA, 表示為如圖關(guān)系

理解了這層引用關(guān)系,對(duì)于delegate 為什么要用weak 修飾符,block可能會(huì)出現(xiàn)循環(huán)引用的解答就有幫助。
2,屬性特質(zhì)
1)原子性(atomic 和 nonatomic)
默認(rèn)是atomic,原子的。兩者的區(qū)別:具有atomic特質(zhì)的獲取方法會(huì)通過(guò)同步鎖機(jī)制來(lái)確保其操作的原子性。比如,兩條線程讀寫統(tǒng)一屬性,如果用atomic,那么不論何時(shí),總能看到有效的屬性值。如果不加鎖的話(使用nonatomic),那么當(dāng)其中一個(gè)線程正在改寫某屬性時(shí),另外一個(gè)線程也許會(huì)突然闖入,把尚未修改好的屬性值讀取出來(lái),這時(shí),線程讀到的屬性值可能不對(duì)。但是,在iOS程序里,所有屬性都是聲明為nonatomic。原因:在iOS中使用同步鎖的開銷比較大,這會(huì)帶來(lái)性能問(wèn)題。還有“原子的”屬性也并不能完全保證線程安全,若要實(shí)現(xiàn)線程安全的操作,還需要更為深層的鎖定機(jī)制才行
2)內(nèi)存管理語(yǔ)義
- assign 基本數(shù)據(jù)類型
- strong 表明該屬性定義了一種"擁有關(guān)系"。為該屬性設(shè)置新值時(shí),設(shè)置方法里會(huì)保留新值,并釋放舊值,然后再將新值設(shè)置上去
- weak 表明該屬性定義了一種"非擁有關(guān)系"。為該屬性設(shè)置新值時(shí),設(shè)置方法里既不會(huì)保留新值,也不會(huì)釋放舊值,同assign類似,只是使用weak,屬性所指的對(duì)象遭到摧毀時(shí),屬性值會(huì)自動(dòng)清空,置為nil。而assign則不會(huì)
- copy 所屬關(guān)系與strong類似,只是設(shè)置方法里并不是保留新值,而是將新值"copy"一份。
- unsafe_unretained 與assign相同,但它適用于對(duì)象類型
3)讀寫權(quán)限
有readwrite 和 readonly 兩種權(quán)限。默認(rèn)是readwrite. 盡量使用不可變對(duì)象,即屬性盡量用readonly修飾
4)方法名
getter = <name> setter=<name>(少用)
3,類簇與工廠模式
示例如下,EOCEmployee是基類,剩下的類都是其子類
typedef NS_ENUM(NSUInteger, EOCEmployeeType) {
EOCEmployeeTypeDesigner,
EOCEmployeeTypeDeveloper,
EOCEmployeeTypeTester,
EOCEmployeeTypeFinance
};
@interface EOCEmployee : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSUInteger salary;
+ (EOCEmployee *)employeeWithType:(EOCEmployeeType)type;
- (void)doADaysWork;
@end
@implementation EOCEmployee
+ (EOCEmployee *)employeeWithType:(EOCEmployeeType)type {
switch (type) {
case EOCEmployeeTypeDesigner:
return [[EOCEmployeeDesigner alloc] init];
break;
case EOCEmployeeTypeDeveloper:
return [[EOCEmployeeDeveloper alloc] init];
break;
case EOCEmployeeTypeTester:
return [[EOCEmployeeTester alloc] init];
break;
case EOCEmployeeTypeFinance:
return [[EOCEmployeeFinance alloc] init];
break;
}
}
- (void)doADaysWork {
//子類自己去實(shí)現(xiàn)。。。
}
@end
子類繼承,實(shí)現(xiàn)父類方法
#import "EOCEmployee.h"
@interface EOCEmployeeDeveloper : EOCEmployee
@end
@implementation EOCEmployeeDeveloper
- (void)doADaysWork {
NSLog(@"i am developer");
}
@end
#import "EOCEmployee.h"
@interface EOCEmployeeDesigner : EOCEmployee
@end
#import "EOCEmployeeDesigner.h"
@implementation EOCEmployeeDesigner
- (void)doADaysWork {
NSLog(@"i am designer...");
}
@end
接下來(lái)test
#import "ViewController.h"
#import "EOCEmployee.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
EOCEmployee *paEmployee = [EOCEmployee employeeWithType:EOCEmployeeTypeDeveloper];
[paEmployee doADaysWork];
// Do any additional setup after loading the view, typically from a nib.
}
@end
以上就是類簇的創(chuàng)建模式。類簇模式可以把實(shí)現(xiàn)細(xì)節(jié)隱藏在一套簡(jiǎn)單的公共接口后面。在系統(tǒng)框架中使用
4,runtime的一些基本知識(shí)
1)C語(yǔ)言使用的是"靜態(tài)綁定",即在編譯器就能決定運(yùn)行時(shí)所應(yīng)調(diào)用的函數(shù),而OC采用的是"動(dòng)態(tài)綁定",只有在運(yùn)行時(shí)才能確定。在底層,對(duì)象收到消息后,究竟該調(diào)用哪個(gè)方法完全在運(yùn)行期決定,甚至可以在程序運(yùn)行時(shí)改變
5,發(fā)郵件 MFMailComposeViewController 使用注意
- 需要導(dǎo)入MessageUI.framework庫(kù)(實(shí)際上,ios10之后就無(wú)需手動(dòng)導(dǎo)入了,為兼容低版本,最好手動(dòng)導(dǎo)入)
2)發(fā)郵件前,需要判斷 MFMailComposeViewController 是否有發(fā)郵件的功能,否則可能會(huì)cresh. 報(bào)錯(cuò)Application tried to present a nil modal view controller on target
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
if ([MFMailComposeViewController canSendMail]) {
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
//Present mail view controller on screen
[self presentViewController:mc animated:YES completion:nil];
}
6,用storyboard創(chuàng)建tableViewCell或者collectionViewCell 時(shí),當(dāng)在storyboard里使用了Identifier,并在代碼里做了匹配時(shí),如下兩圖,就不再需要用代碼提前注冊(cè)cell了,否則會(huì)出錯(cuò)。



7,哪些場(chǎng)景必須要使用@synthesize?
- 同時(shí)重寫了 setter 和 getter 時(shí)
- 重寫了只讀屬性的 getter 時(shí)
- 使用了 @dynamic 時(shí)
- 在 @protocol 中定義的所有屬性
- 在 category 中定義的所有屬性
- 重載的屬性
更多信息:http://stackoverflow.com/questions/19784454/when-should-i-use-synthesize-explicitly/19821816#19821816
8,通知NSNotificationCenter的一點(diǎn)認(rèn)識(shí)
- 我們知道通知是一對(duì)多的關(guān)系,即一處發(fā)通知,多處可接收。假設(shè)有這個(gè)場(chǎng)景:A-->B-->C-->D, push關(guān)系,這4個(gè)控制器全部都在同一個(gè)棧里。當(dāng)在C控制器里點(diǎn)擊確定按鈕push 到D時(shí)發(fā)送通知,并且在 A,B頁(yè)面里都接收這個(gè)通知,在對(duì)應(yīng)通知方法里做某些處理(比如請(qǐng)求數(shù)據(jù),刷新當(dāng)前頁(yè)面...)
之前的認(rèn)知: C push 到D的時(shí)候 發(fā)送通知,A,B即使接收了該通知,也不會(huì)有相應(yīng)的處理,因?yàn)楫?dāng)前response的頁(yè)面是D,而不是它們
經(jīng)過(guò)測(cè)試驗(yàn)證,認(rèn)知是錯(cuò)誤的,只要它們?cè)谕粋€(gè)棧里,有一處發(fā)通知,其他任何有監(jiān)聽這個(gè)通知的地方都會(huì)及時(shí)響應(yīng)并處理,如果考慮性能,這點(diǎn)就不太合理,也就是push 到 D 時(shí)盡量避免給棧內(nèi)的其他控制器發(fā)送通知。代理delegate 應(yīng)該也有如此
9,iOS里通用的數(shù)據(jù)結(jié)構(gòu)有三類:數(shù)組,字典,集合(Set)。
有時(shí)候腦袋不靈光,把最基本的忘記了,通過(guò)看書,把一些基本的知識(shí)點(diǎn)記下來(lái)?!昂糜浶圆蝗鐮€筆頭”,經(jīng)常翻翻以鞏固記憶