一、多線程開發的理解以及iOS中有幾種實現多線程的方法?
好處:
1、使用線程可以把程序中占據時間長的任務放到后臺去處理,如圖片、視頻的下載;
2、發揮多核處理器的優勢,并發執行讓系統運行的更快、更流暢,用戶體驗更好。
缺點:
1、大量的線程降低代碼的可讀性;
2、更多的線程需要更多的內存空間;
3、當多個線程對同一個資源出現爭奪的時候要注意線程安全的問題。
iOS有三種多線程編程的技術:
1、NSThread(兩種創建方式)[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[myThread start];
2、NSOperationQueue
NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init];
oprationQueue addOperationWithBlock:^{
//這個block語句塊在子線程中執行
}
3、Grand Central Dispatch (GCD)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗時的操作
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});
不顯示的創建線程的方法:用NSObject的類方法 performSelectorInBackground:withObject: 創建一個線程:[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
二、線程同步和異步的區別?IOS中如何實現多線程的同步?
同步:一個線程要等待上一個線程執行完之后才能執行當前的線程。
異步:同時去做兩件或者多件事。比如邊聽歌邊看報。
實現:原子操作(atomic)、加鎖(NSLock、NSRecursive、NSConditionLock)、@synchronized GCD串行隊列,GCD當中的屏障,NSOperationQueue設置最大并發數為1
三、iOS本地數據存儲都有哪幾種方式?iOS如何實現復雜對象的存儲?
NSKeyedArchiver(歸檔)采用歸檔的形式來保存數據,該數據對象需要遵守NSCoding協議,并且該對象對應的類必須提供encodeWithCoder:和initWithCoder:方法。
1.NSUserDefaults:用來保存應用程序設置和屬性、用戶保存的數據。用戶再次打開程序或開機后這些數據仍然存在。NSUserDefaults可以存儲的數據類型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。
2.Write寫入方式:永久保存在磁盤中。
3.SQLite(FMDB、CoreData)
NSCoding + NSKeyedArchiver實現復雜對象的存儲。
四、怎樣實現一個singleton的類?
//第一種方式
static LOSingleton * shareInstance;
+( LOSingleton *)sharedInstance{
@synchronized(self){//這個東西其實就是一個加鎖。如果self 其他線程訪問,則會阻塞。這樣做一般是用來對單例進行一個死鎖的保護
if (shareInstance == nil) {
shareInstance = [[super allocWithZone:NULL] init];
}
}
return shareInstance;
}
//第二種方式
- (LOSingleton *) sharedInstance
{
static LOSingleton *sharedInstance = nil ;
static dispatch_once_t onceToken; // 鎖
dispatch_once (& onceToken, ^ { // 最多調用一次
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
五、什么是安全釋放?
在對象release之后把指針置為nil。
六、簡述你對UIView、UIWindow和CALayer的理解
UIView繼承于UIResponder, UIResponder繼承于NSObject,UIView可以響應用戶事件。CALayer繼承于NSObject,所以CALayer不能響應事件。UIView構建界面,UIView側重于對內容的管理,CALayer側重于對內容的繪制。UIView是用來顯示內容的,可以處理用戶事件;CALayer是用來繪制內容的,對內容進行動畫處理,依賴與UIView來進行顯示,不能處理用戶事件。
七、什么是Protocol?什么是代理?寫一個委托的interface?委托的property聲明用什么屬性?為什么?
協議提供了一組方法,但是并不負責實現,如果一個類遵循了某個協議,并且實現了協議里面的方法,那么我們稱這個類就是遵循了某個協議的代理。屬性的聲明使用assign,防止出現循環引用的問題。
八、分別描述類別(categories)和延展(extensions)是什么?以及兩者的區別?繼承和類別在實現中有何區別?為什么Category只能為對象添加方法,卻不能添加成員變量?
category類目:在不知道源碼的情況下為一個類擴展方法;
extension:為一個類聲明私有方法和變量。繼承是創建了一個新的類,而類別只是對類的一個擴展,還是之前的類。類目的作用就是為已知的類添加方法。
九、Objective-C有私有方法么?私有變量呢?如多沒有的話,有沒有什么代替的方法?
objective-c – 類里面的方法只有兩種, 靜態方法和實例方法.
@private來修飾私有變量
OC中所有的實例變量默認都是私有的,所有的實例方法默認都是公有的。
十、objc中的減號與加號代表什么?
+靜態方法,也叫類方法,-實例方法
十一、對于語句NSString* testObject = [[NSData alloc] init];testObject 在編譯時和運行時分別是什么類型的對象?
編譯的時候是NSString類型,運行的時候是NSData類型
十二、OC中是所有對象間的交互是如何實現的?
函數指針實現
十三、#import和#include的區別是什么?#import<> 跟 #import""有什么區別?
1、#import能避免頭文件被重復包含的問題
2、一般來說,導入objective c的頭文件時用#import,包含C/C++頭文件時用#include。
3、#import 確定一個文件只能被導入一次,這使你在遞歸包含中不會出現問題。
4、#import<> 包含iOS框架類庫里的類,#import""包含項目里自定義的類。
5、#import比起#include的好處就是它避免了重復引用的問題。所以在OC中我們基本用的都是import。
十四、Category是什么?擴展一個類的方式用繼承好還是類目好?為什么?
Category是類目。用類目好,因為繼承要滿足a is a b的關系,而類目只需要滿足a has a b的關系,局限性更小,你不用定義子類就能擴展一個類的功能,還能將類的定義分開放在不同的源文件里, 用Category去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關系。
十五、類實例(成員)變量的@protected,@private,@public聲明各有什么含義?
@protected:受保護的,該實例變量只能在該類和其子類內訪問,其他類內不能訪問。
@private:私有的,該實例變量只能在該類內訪問,其他類內不能訪問。
@public:共有的,該實例變量誰都可以訪問。
十六、id聲明的對象有什么特性?
1、沒有 * 號
2、動態數據類型
3、可以指向任何類的對象(設置是nil),而不關心其具體類型
4、在運行時檢查其具體類型
5、可以對其發送任何(存在的)消息
十七、內存管理的幾條原則是什么?按照默認法則,哪些關鍵字生成的對象需要手動釋放?哪些情況下不需要手動釋放,會直接進入自動釋放池?
內存管理的原則是:誰創建,誰釋放;誰引用,誰管理。
遵循Cocoa Touch的使用原則;
內存管理主要要避免“過早釋放”和“內存泄漏”,對于“過早釋放”需要注意@property設置特性時,一定要用對特性關鍵字,對于“內存泄漏”,一定要申請了要負責釋放,要細心。
1、當使用new、alloc或copy方法創建一個對象時,該對象引用計數器為1。如果不需要使用該對象,可以向其發送release或autorelease消息,在其使用完畢時被銷毀。
2、如果通過其他方法獲取一個對象,則可以假設這個對象引用計數為1,并且被設置為autorelease,不需要對該對象進行清理,如果確實需要retain這個對象,則需要使用完畢后release。
3、如果retain了某個對象,需要release或autorelease該對象,保持retain方法和release方法使用次數相等。
4、使用new、alloc、copy關鍵字生成的對象和retain了的對象需要手動釋放。設置為autorelease的對象不需要手動釋放,會直接進入自動釋放池。
十八、屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那種情況下用?
assign用于簡單數據類型,如NSInteger,double,bool;
retain和copy用于對象;
readwrite是可讀可寫特性;需要生成getter方法和setter方法時;
readonly是只讀特性 只會生成getter方法 不會生成setter方法 ,不希望屬性在類外改變;
assign是賦值特性,setter方法將傳入參數賦值給實例變量;僅設置變量時;
retain表示持有特性,setter方法將傳入參數先保留,再賦值,傳入參數的retaincount會+1;
copy表示賦值特性,setter方法將傳入對象復制一份;需要完全一份新的變量時;
nonatomic非原子操作,決定編譯器生成的setter getter是否是原子操作,atomic表示多線程安全,一般使用nonatomic。
十九、Objective-C如何對內存管理的,說說你的看法和解決方法?
Objective-C的內存管理主要有三種方式ARC(自動內存計數)、手動內存計數、內存池。
二十、那些關鍵字生成的對象 需要手動釋放?
關鍵字alloc 或new 生成的對象需要手動釋放
二十一、如何對iOS設備進行性能測試?
Profile-> Instruments ->Time Profiler
二十二、Category是什么?重寫一個類的方式用繼承好還是分類好?為什么?
Category是類別,一般情況用分類好,用Category去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關系。
二十三、Object C中創建線程的方法是什么?如果在主線程中執行代碼,方法是什么?如果想延時執行代碼、方法又是什么?
線程創建有三種方法:使用NSThread創建、使用 GCD的dispatch、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執行代碼,方法是 performSelectorOnMainThread,如果想延時執行代碼可以用performSelector:onThread:withObject:waitUntilDone
二十四、什么是Notification?什么時候用delegate,什么時候用Notification?
觀察者模式,controller向defaultNotificationCenter添加自己的notification,其他類注冊這個notification就可以收到通知,這些類可以在收到通知時做自己的操作(多觀察者默認隨機順序發通知給觀察者們,而且每個觀察者都要等當前的某個觀察者的操作做完才能輪到他來操作,可以用NotificationQueue的方式安排觀察者的反應順序,也可以在添加觀察者中設定反映時間,取消觀察需要在viewDidUnload 跟dealloc中都要注銷)。
delegate針對one-to-one關系,并且reciever可以返回值給sender,notification 可以針對one-to-one/many/none,reciever無法返回值給sender.所以,delegate用于sender希望接受到reciever的某個功能反饋值,notification用于通知多個object某個事件。