搜集于互聯(lián)網(wǎng),如有侵權(quán)希太,刪之克饶。
1.屬性readwrite,readonly誊辉,assign矾湃,retain,copy堕澄,nonatomic 各是什么作用邀跃,在那種情況下用霉咨?
- readwrite 是可讀可寫特性;需要生成getter方法和setter方法時;
- readonly 是只讀特性 只會生成getter方法 不會生成setter方法 ;不希望屬性在類外改變時坞嘀;
- assign 是賦值特性躯护,setter方法將傳入?yún)?shù)賦值給實例變量;僅設置變量時,一般用于基礎(chǔ)數(shù)據(jù)類型;
- retain 表示持有特性丽涩,setter方法將傳入?yún)?shù)先保留棺滞,再賦值,傳入?yún)?shù)的retaincount會+1矢渊,也就是說release舊值继准,retain新值;一般用于OC對象;
- copy 表示賦值特性矮男,setter方法將傳入對象復制一份;需要完全一份新的變量時移必,也就是release舊值,copy新值毡鉴;一般用于NSString\NSMutableString\block崔泵;
6.nonatomic 非原子操作,決定編譯器生成的setter getter是否是原子操作猪瞬,atomic表示多線程安全憎瘸,一般使用nonatomic。
2.#import 跟#include陈瘦、@class有什么區(qū)別幌甘?#import<> 跟 #import”"又什么區(qū)別?
1.#import和#include都能完整地包含某個文件的內(nèi)容痊项,#import能防止同一個文件被包含多次。
- @class和#import
作用上的區(qū)別:
#import會包含引用類的所有信息(內(nèi)容), 包括引用類的變量和方法皱埠;
@class僅僅是告訴編譯器有這么一個類, 具體這個類里有什么信息, 完全不知咖驮;
效率上的區(qū)別:
如果有上百個頭文件都#import了同一個文件游沿,或者這些文件依次被#import,那么一旦最開始的頭文件稍有改動,后面引用到這個文件的所有類都需要重新編譯一遍 , 編譯效率非常低袋坑;
相對來講枣宫,使用@class方式就不會出現(xiàn)這種問題了 -
import <> 用來包含系統(tǒng)自帶的文件,#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介衔,當對象的計數(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蔓榄、淺復制和深復制的區(qū)別?
淺復制:只復制指向?qū)ο蟮闹羔樐眨粡椭埔脤ο蟊旧怼?br>
深復制:復制引用對象本身。
意思就是說我有個A對象澜搅,復制一份后得到A_copy對象后勉躺,對于淺復制來說觅丰,A和A_copy指向的是同一個內(nèi)存資源妇萄,復制的只不過是是一個指針,對象本身資源還是只有一份轻掩,那如果我們對A_copy執(zhí)行了修改操作,那么發(fā)現(xiàn)A引用的對象同樣被修改唇牧,這其實違背了我們復制拷貝的一個思想。深復制就好理解了,內(nèi)存中存在了兩份獨立對象本身壳影。
用通俗的話講就是:淺復制好比你和你的影子宴咧,你完蛋径缅,你的影子也完蛋;深復制好比你和你的克隆人氧卧,你完蛋沙绝,你的克隆人還活著鼠锈。
7购笆、分類的作用?分類和繼承的區(qū)別样傍?
分類可以在不獲悉衫哥,不改變原來代碼的情況下往里面添加新的方法娃循,只能添加斗蒋,不能刪除修改泉沾,并且如果分類和原來類中的方法產(chǎn)生名稱沖突,則分類將覆蓋原來的方法姓迅,因為分類具有更高的優(yōu)先級丁存。
繼承可以增加,修改或者刪除方法扩然,并且可以增加屬性聋伦;但是分類只能添加方法觉增,不能刪除修改,也不能增加屬性说铃。
8截汪、frame和bounds有什么不同?
frame指的是:該view在父view坐標系統(tǒng)中的位置和大小植捎。(參照點是父親的坐標系統(tǒng))
bounds指的是:該view在本身坐標系統(tǒng)中 的位置和大小焰枢。(參照點是本身坐標系統(tǒng))
9、HTTP協(xié)議中暑椰,POST和GET的區(qū)別是什么一汽?
1.GET 方法:
- GET 方法提交數(shù)據(jù)不安全低滩,數(shù)據(jù)置于請求行,客戶端地址欄可見;
- GET 方法提交的數(shù)據(jù)大小有限
- GET 方法不可以設置書簽
2.POST 方法: - POST 方法提交數(shù)據(jù)安全监憎,數(shù)據(jù)置于消息主體內(nèi)鲸阔,客戶端不可見
- POST 方法提交的數(shù)據(jù)大小沒有限制
- POST 方法可以設置書簽
10、視圖控制器的生命周期方法調(diào)用順序类少?
11瞒滴、block和代理的區(qū)別赞警,哪個更好?
代理回調(diào)更面向過程世剖,block更面向結(jié)果旁瘫。如果需要在執(zhí)行的不同步驟時被通知琼蚯,你就要使用代理遭庶。如果只需要請求的消息或者失敗的詳情,應該使用block翎苫。block更適合與狀態(tài)無關(guān)的操作煎谍,比如被告知某些結(jié)果龙屉,block之間是不會相互影響的。但是代理更像一個生產(chǎn)流水線作岖,每個回調(diào)方法是生產(chǎn)線上的一個處理步驟鳍咱,一個回調(diào)的變動可能會引起另一個回調(diào)的變動与柑。要是一個對象有超過一個的不同事件,應該使用代理丑念。一個對象只有一個代理结蟋,要是某個對象是個單例對象嵌屎,就不能使用代理。要是一個對象調(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ù)非常大時慰毅,應該如何修改事富?
- 解決辦法1:如果i比較大乘陪,可以用@autoreleasepool {}解決啡邑,放在for循環(huán)外,循環(huán)結(jié)束后贵扰,銷毀創(chuàng)建的對象流部,解決占據(jù)棧區(qū)內(nèi)存的問題
- 解決方法2:如果i玩命大枝冀,一次循環(huán)都會造成自動釋放池被填滿耘子,自動釋放池放在for循環(huán)內(nèi)谷誓,每次循環(huán)都將上一次創(chuàng)建的對象release捍歪。
13鸵钝、iOS怎么做數(shù)據(jù)的持久化?
1.plist屬性列表 - 適用對象:僅僅是Foundation框架中自帶的一些類,比如NSString弓摘、韧献、NSArray研叫、NSDictionary嚷炉、NSSet、NSNumber绘证、NSData
- 調(diào)用對象的writeToFile...方法就可以寫入文件
- 調(diào)用對象的...WithContentsOfFile方法就可以從文件中讀取對象內(nèi)容
2.偏好設置(NSUserDefault) - 本質(zhì)還是plist屬性列表的方式進行存儲
- 存取非常簡單(不關(guān)心文件夾和文件名)
- 缺點:只能存儲到一個文件中(不能存放大批量數(shù)據(jù))
3.NSCoding - 能將任何遵守了NSCoding協(xié)議的對象塞進文件中
-
- (void)encodeWithCoder:(NSCoder *)encoder
將對象歸檔的時候會調(diào)用(將對象寫入文件之前會調(diào)用)這個方法嚷那, 在這個方法說清楚:a杆煞、那些屬性需要存儲 b决乎、怎樣存儲這些屬性; -
- (id)initWithCoder:(NSCoder *)decoder
當從文件中解析對象的時候調(diào)用這個方法蚌斩,在這個方法說清楚:a送膳、那些屬性需要解析(讀取) b肠缨、怎樣解析(讀壬罐取)這些屬性名斟; - 如果父類也有屬性需要歸檔或者讀檔,必須調(diào)用super的encodeWithCoder:和initWithCoder:方法闷袒。
14岩梳、APNS的推送機制
首先我們看一下蘋果官方給出的對iOS推送機制的解釋冀值。如下圖:
Provider就是我們自己程序的后臺服務器列疗,APNS是Apple Push Notification Service的縮寫,也就是蘋果的推送服務器告材。
上圖可以分為三個階段:
第一階段:應用程序的服務器端把要發(fā)送的消息斥赋、目的iPhone的標識打包产艾,發(fā)給APNS。
第二階段:APNS在自身的已注冊Push服務的iPhone列表中骚露,查找有相應標識的iPhone棘幸,并把消息發(fā)送到iPhone倦零。
第三階段:iPhone把發(fā)來的消息傳遞給相應的應用程序吨悍,并且按照設定彈出Push通知育瓜。
15躏仇、控制器View的加載過程腺办?
當程序訪問了控制器的View屬性時會先判斷控制器的View是否存在怀喉,如果存在就直接返回已經(jīng)存在的View;如果不存在躲履,就會先調(diào)用loadView
這個方法聊闯;如果控制器的loadView
方法實現(xiàn)了馅袁,就會按照loadView
方法加載自定義的View;如果控制器的loadView
方法沒有實現(xiàn)就會判斷storyboard是否存在犹褒;如果storyboard存在就會按照storyboard加載控制器的View叠骑;如果storyboard不存在削茁,就會創(chuàng)建一個空視圖返回。
16慰丛、UITableView的數(shù)據(jù)源方法和代理方法诅病?
數(shù)據(jù)源常見方法:
1.有多少組
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
2.第section組頭部控件有多高
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
3.第section組有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
4.indexPath這行的cell有多高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
5.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對象的重用原理:當滾動列表時板辽,部分UITableViewCell會移出窗口戳气,UITableView會將窗口外的UITableViewCell放入一個對象池中巧鸭,等待重用麻捻。當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的時候傳入一個特定的字符串標識來設置reuseIdentifier(一般用UITableViewCell的類名)耀怜。當UITableView要求dataSource返回UITableViewCell時桐愉,先通過一個字符串標識到對象池中查找對應類型的UITableViewCell對象从诲,如果有,就重用俊性,如果沒有描扯,就傳入這個字符串標識來初始化一個UITableViewCell對象绽诚。
18、在一個對象的方法里面:self.name = @"object";
和name =@"object";
有什么不同嗎?
self.name = @"object";
會調(diào)用對象的setName()方法卒落,name =@"object";
會直接把@"object"
賦值給當前對象的name 屬性导绷。
19屎飘、為什么很多內(nèi)置類如UITableViewController的delegate屬性都是assign而不是retain的?
會引起循環(huán)引用
所有的引用計數(shù)系統(tǒng)檐盟,都存在循環(huán)應用的問題葵萎。例如下面的引用關(guān)系:
? 對象a創(chuàng)建并引用到了對象b.
? 對象b創(chuàng)建并引用到了對象c.
? 對象c創(chuàng)建并引用到了對象b.這時候b和c的引用計數(shù)分別是2和1。
當a不再使用b羡忘,調(diào)用release釋放對b的所有權(quán),因為c還引用了b节猿,所以b的引用計數(shù)為1漫雕,b不會被釋放。b不釋放太雨,c的引用計數(shù)就是1囊扳,c也不會被釋放梅惯。從此铣减,b和c永遠留在內(nèi)存中脚作。這種情況,必須打斷循環(huán)引用劣针,通過其他規(guī)則來維護引用關(guān)系捺典。我們常見的delegate往往是assign方式的屬性而不是retain方式 的屬性从祝,賦值不會增加引用計數(shù)牍陌,就是為了防止delegation兩端產(chǎn)生不必要的循環(huán)引用。如果一個UITableViewController 對象a通過retain獲取了UITableView對象b的所有權(quán)贮预,這個UITableView對象b的delegate又是a仿吞, 如果這個delegate是retain方式的,那基本上就沒有機會釋放這兩個對象了误趴。自己在設計使用delegate模式時凉当,也要注意這點售葡。
20、什么是Notification楼雹?
觀察者模式贮缅,controller向defaultNotificationCenter添加自己的notification介却,其他類注冊這個notification就可以收到通知齿坷,這些類可以在收到通知時做自己的操作(多觀察者默認隨機順序發(fā)通知給觀察者們,而且每個觀察者都要等當前的某個觀察者的操作做完才能輪到他來操作崎场,可以用NotificationQueue的方式安排觀察者的反應順序谭跨,也可以在添加觀察者中設定反映時間李滴,取消觀察需要在viewDidUnload 跟dealloc中都要注銷)。
21污呼、單例模式的作用燕酷?程序中有哪些常見的單例?單例的實現(xiàn)步驟?
- 單例模式的作用是解決“應用中只有一個實例”的一類問題苗缩。
- dispatch_once函數(shù)是由GCD提供的酱讶,它的作用是在整個應用程序生命周期中只執(zhí)行一次代碼塊。dispatch_once_t是由GCD提供的結(jié)構(gòu)體渊迁,使用時需要將GCD地址傳給dispatch_once函數(shù)琉朽。dispatch_once函數(shù)能夠記錄該代碼是否被調(diào)用過稚铣。
- dispatch_once函數(shù)不僅意味著代碼僅會被執(zhí)行一次惕医,而且還意味著此運行還是線程同步的。也就是說螟够,當我們使用dispatch_once函數(shù)時沛简,就不需要再使用諸如@synchronized之類的語句椒楣。
- 應用案例:UIApplication捧灰、NSUserDefaults统锤、NSNotificationCenter饲窿、NSFileManager、NSBundle
- UIApplication:
UIApplication類的實例提供了應用程序的集中控制點來保持應用的狀態(tài)阀溶。UIApplication實例總是分配給應用程序委托對象(UIApplicationDelegate),通過應用程序委托對象來響應低內(nèi)存永品、應用啟動击纬、后臺運行和應用終止等事件更振。 - NSUserDefaults:
單例類NSUserDefaults可以很方便的讀取應用設置項目。 - NSNotificationCenter:
單例類NSNotificationCenter提供信息廣播通知谋作,它采用觀察者模式的通知機制遵蚜。 - NSFileManager:
NSFileManager提供了訪問文件系統(tǒng)的通用操作奈惑,可以定位、創(chuàng)建寂殉、復制文件和文件夾友扰。 - NSBundle:
NSBundle提供了動態(tài)加載(或卸載)可執(zhí)行代碼庶柿、定位資源文件以及資源文件本地化浮庐、訪問系統(tǒng)文件等功能。 - 要實現(xiàn)一個Singleton Class, 至少需要做以下四個步驟:
- 為Singleton Object實現(xiàn)一個靜態(tài)實例, 初始化, 然后設置成nil.
- 實現(xiàn)一個實例構(gòu)造方法(通常命名為 sharedInstance 或者 sharedManager)檢查上面聲名的靜態(tài)實例是否為nil, 如果是則新建并返回一個本類實例.
- 重寫 allocWithZone: 方法來保證當其他人直接使用 alloc 和 init 試圖獲得一個新實例的時候不會產(chǎn)生一個新的實例.
- 適當?shù)膶崿F(xiàn) copyWithZone:, release, retain, retainCount 和 autorelease.
22梭域、block使用時的注意點病涨?
Block可以使用在定義之前聲明的局部變量璧坟;
int i = 10;
void(^myBlock)() = ^{
NSLog(@"%d", i);
};
i = 100;
myBlock();
注意:
- 在定義Block時,會在Block中建立當前局部變量內(nèi)容的副本(拷貝)
- 后續(xù)再對該變量的數(shù)值進行修改循衰,不會影響B(tài)lock中的數(shù)值
- 如果需要在block中保持局部變量的數(shù)值變化,需要使用__block關(guān)鍵字
- 使用__block關(guān)鍵字后伐蒋,同樣可以在Block中修改該變量的數(shù)值
- 不能直接用點語法調(diào)用self的方法先鱼,會造成循環(huán)引用奸鬓,要用中括號調(diào)用。
22宏多、@private澡罚、@protected留搔、@public、@package類型的成員變量的作用域隔显? - @private:只能在當前類的對象方法中訪問括眠;
- @protected:可以在當前類以及子類的實現(xiàn)中直接訪問,默認類型捐下;
- @public:任何地方都可以直接訪問對象的成員變量萌业;
- @package:同一個“體系內(nèi)”(框架)可以訪問生年;
23抱婉、這個寫法會出什么問題:@property (copy) NSMutableArray *array;
?
@property 的setter方法設置成copy以后,array這個指針指向的是一個不可變數(shù)組蒸绩,那么當使用點語法為給array賦值時,就會發(fā)生“unrecognized selector sent to instance”錯誤传蹈,程序就會崩潰惦界。