1.屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那種情況下用?
2.#import 跟#include、@class有什么區(qū)別?#import<> 跟 #import”"又什么區(qū)別?
1).#import和#include都能完整地包含某個文件的內(nèi)容,#import能防止同一個文件被包含多次。
2). @class和#import
3.OC有多繼承嗎?沒有的話用什么代替?
OC中沒有多繼承,可以用委托代理PRotocol來實現(xiàn)。
4.Objective-C如何對內(nèi)存管理的?內(nèi)存管理的原則是?
Objective-C的內(nèi)存管理主要有三種方式ARC(自動引用計數(shù))、MRC(手動內(nèi)存計數(shù))、autorelease(自動釋放池)。
每個對象都有一個引用計數(shù)器,每個新對象的計數(shù)器是1,當(dāng)對象的計數(shù)器減為0時,就會被銷毀。
?內(nèi)存管理原則(配對原則):只要出現(xiàn)了 new/alloc/retain,就一定配對出現(xiàn)一個release/autorelease。
5、Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼,方法是什么?如果想延時執(zhí)行代碼、方法又是什么?
線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建、使用GCD的dispatch、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼,方法是performSelectorOnMainThread,如果想延時執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:;
6、淺復(fù)制和深復(fù)制的區(qū)別?
淺復(fù)制:只復(fù)制指向?qū)ο蟮闹羔槪粡?fù)制引用對象本身。
深復(fù)制:復(fù)制引用對象本身。
意思就是說我有個A對象,復(fù)制一份后得到A_copy對象后,對于淺復(fù)制來說,A和A_copy指向的是同一個內(nèi)存資源,復(fù)制的只不過是是一個指針,對象本身資源還是只有一份,那如果我們對A_copy執(zhí)行了修改操作,那么發(fā)現(xiàn)A引用的對象同樣被修改,這其實違背了我們復(fù)制拷貝的一個思想。深復(fù)制就好理解了,內(nèi)存中存在了兩份獨立對象本身。
用通俗的話講就是:淺復(fù)制好比你和你的影子,你完蛋,你的影子也完蛋;深復(fù)制好比你和你的克隆人,你完蛋,你的克隆人還活著。
7、分類的作用?分類和繼承的區(qū)別?
分類可以在不獲悉,不改變原來代碼的情況下往里面添加新的方法,只能添加,不能刪除修改,并且如果分類和原來類中的方法產(chǎn)生名稱沖突,則分類將覆蓋原來的方法,因為分類具有更高的優(yōu)先級。
繼承可以增加,修改或者刪除方法,并且可以增加屬性;但是分類只能添加方法,不能刪除修改,也不能增加屬性。
8、frame和bounds有什么不同?
frame指的是:該view在父view坐標(biāo)系統(tǒng)中的位置和大小。(參照點是父親的坐標(biāo)系統(tǒng))
bounds指的是:該view在本身坐標(biāo)系統(tǒng)中 的位置和大小。(參照點是本身坐標(biāo)系統(tǒng))
9、HTTP協(xié)議中,POST和GET的區(qū)別是什么?
1).GET 方法:
11、block和代理的區(qū)別,哪個更好?
代理回調(diào)更面向過程,block更面向結(jié)果。如果需要在執(zhí)行的不同步驟時被通知,你就要使用代理。如果只需要請求的消息或者失敗的詳情,應(yīng)該使用block。block更適合與狀態(tài)無關(guān)的操作,比如被告知某些結(jié)果,block之間是不會相互影響的。但是代理更像一個生產(chǎn)流水線,每個回調(diào)方法是生產(chǎn)線上的一個處理步驟,一個回調(diào)的變動可能會引起另一個回調(diào)的變動。要是一個對象有超過一個的不同事件,應(yīng)該使用代理。一個對象只有一個代理,要是某個對象是個單例對象,就不能使用代理。要是一個對象調(diào)用方法需要返回一些額外的信息,就可能需要使用代理。
12、自動釋放池常見面試代碼
for (int i = 0; i < 10; ++i) {??? NSString *str = @"Hello World";??? str = [str stringByAppendingFormat:@" - %d", i];??? str = [str uppercaseString];??? NSLog(@"%@", str);}
問:以上代碼存在什么樣的問題?如果循環(huán)的次數(shù)非常大時,應(yīng)該如何修改?
- (void)encodeWithCoder:(NSCoder *)encoder
?將對象歸檔的時候會調(diào)用(將對象寫入文件之前會調(diào)用)這個方法,?在這個方法說清楚:a、那些屬性需要存儲? b、怎樣存儲這些屬性;- (id)initWithCoder:(NSCoder *)decoder
當(dāng)從文件中解析對象的時候調(diào)用這個方法,在這個方法說清楚:a、那些屬性需要解析(讀?。?b、怎樣解析(讀?。┻@些屬性;loadView
這個方法;如果控制器的loadView
方法實現(xiàn)了,就會按照loadView
方法加載自定義的View;如果控制器的loadView
方法沒有實現(xiàn)就會判斷storyboard是否存在;如果storyboard存在就會按照storyboard加載控制器的View;如果storyboard不存在,就會創(chuàng)建一個空視圖返回。1.有多少組- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView2.第section組頭部控件有多高- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section3.第section組有多少行- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section4.indexPath這行的cell有多高- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath5.indexPath這行的cell長什么樣子- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 6.第section組頭部顯示什么控件- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
代理方法:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView //右側(cè)索引- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath //行點擊事件NSIndexPath *path = [self.tableView indexPathForSelectedRow]; //獲得被選中的indexPath可以得到section,row[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForSelectedRows] withRowAnimation:UITableViewRowAnimationNone]; //刷新table指定行的數(shù)據(jù)? ? ? ?[self.tableView reloadData]; //刷新table所有行的數(shù)據(jù)
17、UITableViewCell表格優(yōu)化?
UITableViewCell對象的重用原理:當(dāng)滾動列表時,部分UITableViewCell會移出窗口,UITableView會將窗口外的UITableViewCell放入一個對象池中,等待重用。當(dāng)UITableView要求dataSource返回UITableViewCell時,dataSource會先查看這個對象池,如果池中有未使用的UITableViewCell,dataSource會用新的數(shù)據(jù)配置這個UITableViewCell,然后返回給UITableView,重新顯示到窗口中,從而避免創(chuàng)建新對象。
還有一個非常重要的問題:有時候需要自定義UITableViewCell(用一個子類繼承UITableViewCell),而且每一行用的不一定是同一種UITableViewCell(如短信聊天布局),所以一個UITableView可能擁有不同類型的UITableViewCell,對象池中也會有很多不同類型的UITableViewCell,時可能會得到錯誤類型的UITableViewCell那么UITableView在重用UITableViewCell。解決方案:UITableViewCell有個NSString *reuseIdentifie
r屬性,可以在初始化UITableViewCell的時候傳入一個特定的字符串標(biāo)識來設(shè)置reuseIdentifier(一般用UITableViewCell的類名)。當(dāng)UITableView要求dataSource返回UITableViewCell時,先通過一個字符串標(biāo)識到對象池中查找對應(yīng)類型的UITableViewCell對象,如果有,就重用,如果沒有,就傳入這個字符串標(biāo)識來初始化一個UITableViewCell對象。
18、在一個對象的方法里面:self.name = @"object";
和name =@"object";
有什么不同嗎?self.name = @"object";
會調(diào)用對象的setName()方法,name =@"object";
會直接把@"object"
賦值給當(dāng)前對象的name 屬性。
19、為什么很多內(nèi)置類如UITableViewController的delegate屬性都是assign而不是retain的?
會引起循環(huán)引用
所有的引用計數(shù)系統(tǒng),都存在循環(huán)應(yīng)用的問題。例如下面的引用關(guān)系:
? 對象a創(chuàng)建并引用到了對象b.
? 對象b創(chuàng)建并引用到了對象c.
? 對象c創(chuàng)建并引用到了對象b.這時候b和c的引用計數(shù)分別是2和1。
當(dāng)a不再使用b,調(diào)用release釋放對b的所有權(quán),因為c還引用了b,所以b的引用計數(shù)為1,b不會被釋放。b不釋放,c的引用計數(shù)就是1,c也不會被釋放。從此,b和c永遠(yuǎn)留在內(nèi)存中。這種情況,必須打斷循環(huán)引用,通過其他規(guī)則來維護(hù)引用關(guān)系。我們常見的delegate往往是assign方式的屬性而不是retain方式 的屬性,賦值不會增加引用計數(shù),就是為了防止delegation兩端產(chǎn)生不必要的循環(huán)引用。如果一個UITableViewController 對象a通過retain獲取了UITableView對象b的所有權(quán),這個UITableView對象b的delegate又是a, 如果這個delegate是retain方式的,那基本上就沒有機(jī)會釋放這兩個對象了。自己在設(shè)計使用delegate模式時,也要注意這點。
20、什么是Notification?
觀察者模式,controller向defaultNotificationCenter添加自己的notification,其他類注冊這個notification就可以收到通知,這些類可以在收到通知時做自己的操作(多觀察者默認(rèn)隨機(jī)順序發(fā)通知給觀察者們,而且每個觀察者都要等當(dāng)前的某個觀察者的操作做完才能輪到他來操作,可以用NotificationQueue的方式安排觀察者的反應(yīng)順序,也可以在添加觀察者中設(shè)定反映時間,取消觀察需要在viewDidUnload 跟dealloc中都要注銷)。
21、單例模式的作用?程序中有哪些常見的單例?單例的實現(xiàn)步驟?
適當(dāng)?shù)膶崿F(xiàn) copyWithZone:, release, retain, retainCount 和 autorelease.
22、block使用時的注意點?
Block可以使用在定義之前聲明的局部變量;
int i = 10;void(^myBlock)() = ^{ ??? NSLog(@"%d", i);};i = 100;myBlock();
注意:@property (copy) NSMutableArray *array;
?新聞熱點
疑難解答