前言:面試筆試都是必考語法知識點。請認真復習和深入研究OC。
1. UDID&UUID
UDID
是 Unique Device Identifier 的縮寫,中文意思是設備唯一標識.在很多需要限制一臺設備一個賬號的應用中經常會用到,在 Symbian 時代,我們是使用 IMEI 作為設備的唯一標識的,可惜的是 Apple 官方不允許開發者獲得設備的 IMEI.
[UIDevice currentDevice] uniqueIdentifier]
但是我們需要注意的一點是,對于已越獄了的設備,UDID 并不是唯一的.使用 Cydia 插件 UDIDFaker,可以為每一個應用分配不同的 UDID. 所以 UDID 作為標識唯一設備的用途已經不大 了.
UUID
是 Universally Unique Identifier 的縮寫,中文意思是通用唯一識別碼.由網上資料顯示,UUID 是一個軟件建構的標準,也是被開源軟件基金會(Open Software Foundation,OSF)的組織在分布式計算環境(Distributed Computing Environment,DCE)領域的 一部份.UUID 的目的,是讓分布式系統中的所有元素,都能有唯一的辨識資訊,而不需要透過中央 控制端來做辨識資 訊的指定.
備注:UDID 并不是一定不會變,如:重新開關機、手機越獄都會變。決絕辦法是將 UDID 保存在鑰匙串中,用時去鑰匙串中取。UUID 倒是永遠不變的,使用 xcode 可以獲取,但是沒辦 反通過代碼獲取。
2. CPU&GPU
CPU:中央處理器(英文 Central Processing Unit)是一臺計算機的運算核心和控制核心。 CPU、內部存儲器和輸入/輸出設備是電子計算機三大核心部件。其功能主要是解釋計算機指令 以及處理計算機軟件中的數據。
GPU:英文全稱 Graphic Processing Unit,中文翻譯為“圖形處理器”。一個專門的圖形 核心處理器。GPU 是顯示卡的“大腦”,決定了該顯卡的檔次和大部分性能,同時也是 2D 顯示 卡和 3D 顯示卡的區別依據。2D 顯示芯片在處理 3D 圖像和特效時主要依賴 CPU 的處理能力,稱 為“軟加速”。3D 顯示芯片是將三維圖像和特效處理功能集中在顯示芯 片內,也即所謂的“硬 件加速”功能。
3.點(pt)&像素(px)
像素(pixels) 是數碼顯示上最小的計算單位。在同一個屏幕尺寸,更高的 PPI(每英寸 的像素數目),就能顯示更多的像素,同時渲染的內容也會更清晰。
點(points) 是一個與分辨率無關的計算單位。根據屏幕的像素密度,一個點可以包含多 個像素(例如,在標準 Retina 顯示屏上 1 pt 里有 2 x 2 個像素)。
當你為多種顯示設備設計時,你應該以“點”為單位作參考,但設計還是以像素為單位設計的。 這意味著仍然需要以 3 種不同的分辨率導出你的素材,不管你以哪種分辨率設計你的應用。
4. 屬性與成員變量:
成員變量是不與外界接觸的變量,應用于類的內部,如果你說那用@Public 外部不就是可以訪 問了么。簡單的說 public 只能適當使用,不要泛濫,否則就像你把鑰匙插在你自己家門上了。 誰來都可以開門。毫無安全性。
由于成員變量的私有性,為了解決外部訪問的問題就有了屬性變量。屬性變量個人認為最大的 好處就是讓其他對象訪問這個變量。而且你可以設置只讀、可寫等等屬性,同時設置的方法我 們也可以自己定義。記住一點,屬性變量主要是用于與其他對象相互交互的變量
如果對于上面所說還是含糊不清那就記住這幾點吧!
1.只有類內使用,屬性為 private,那么就定義成員變量。 2.如果你發現你需要的這個屬性需要是 public 的,那么毫不猶豫就用屬性在.h 中定義。 3.當你自己內部需要 setter 實現一些功能的時候,用屬性在.m 中定義。 4.當你自己內部需要 getter 實現一些功能的時候,用屬性在.m 中定義。
5. 全局變量和靜態變量的區別:
1> 修飾符
全局變量在聲明源文件之外使用,需要extern引用一下; 靜態變量使用static來修飾
2> 存儲地址
兩者都是存儲在靜態存儲區,非堆棧上,它們與局部變量的存儲分開
3> 生命周期
兩者都是在程序編譯或加載時由系統自動分配的,程序結束時消亡
4> 外部可訪問性
全局變量在整個程序的任何地方均可訪問,而靜態變量相當于面向對象中的私有變量,他的 可訪問性只限定于聲明它的那個源文件,即作用于僅局限于本文件中
6. 分類 拓展 協議中哪些可以聲明屬性?
都可以,但分類和協議創建的屬性只相當于方法,但是內部沒有對成員變量的操作(無法創 建成員變量),拓展可以(私有成員變量)
代理中聲明屬性,沒有實際創建成員變量,相當于聲明了屬性名對應的訪問方法,遵守協議 的類需要實現對應的訪問器方法,否則運行報錯
分類中聲明屬性,警告??示需要手動實現訪問器方法(Swift中叫計算型屬性),而分類中不 能創建成員變量,可以在手寫訪問器方法中使用runtime的 objc_setAssociatedObject方法關 聯對象間接創建屬性(靜態庫添加屬性)
拓展里可以聲明屬性,直接可以使用
7. 繼承和類別的區別
答:(1)使用繼承:
繼承可以增加,修改或者刪除方法,并且可以增加屬性。 添加新方法和父類方法一致,但父類方法仍需要使用
(2)類別:
1> 針對系統提供的一些類,系統本身不提倡繼承,因為這些類的內部實現對繼承有所限制 2> 類別可以將自己構建的類中的方法進行分組,對于大型的類,??高可維護性
(3)分類的作用
1> 將類的實現分散到多個不同文件或多個不同框架中。 2> 創建對私有方法的前向引用。 3> 向對象添加非正式協議。 (非正式協議:即NSObject的分類,聲明方法可以不實現,OC2.0以前protocal沒有@optional,主要使用分類添加可選協議方法 oc中聲明方法不實現,不調用則只警告不報錯 正式協議的優點:可繼承,泛型約束 如kvo的observeValueForKeyPath屬于nsobject的分類,且不需要調父類,說明可選實現該 方法,沒警告可能是編譯器規則過濾) 4> category 可以在不獲悉,不改變原來代碼的情況下往里面添加新的方法,只能添加,不 能刪除修改。 并且如果類別和原來類中的方法產生名稱沖突,則類別將覆蓋原來的方法,因為 類別具有更高的優先級。
(5)分類的局限性
無法向類中添加新的實例變量,類別沒有位置容納實例變量。 無法添加實例變量的局限可以使用字典對象解決。
8. category&extension
類別主要有三個作用
(1)可以將類的實現分散到多個不同文件或多個不同框架中,方便代碼管理。也可以對框架 ??供類的擴展(沒有源碼,不能修改)。 (2)創建對私有方法的前向引用:如果其他類中的方法未實現,在你訪問其他類的私有方法時 編譯器報錯這時使用類別,在類別中聲明這些方法(不必??供方法實現),編譯器就不會再 產生警告 (3)向對象添加非正式協議:創建一個 NSObject 的類別稱為“創建一個非正式協議”,因 為可以作為任何類的委托對象使用。
他們的主要區別是:
1、形式上來看,extension 是匿名的 category。 2、extension 里聲明的方法需要在 main implementation 中實現,category 不強制要求。 3、extension 可以添加屬性(變量),category 不可以。
Category 和 Extension 都是用來給已定義的類增加新的內容的。
4、Category 和原有類的耦合更低一些,聲明和實現都可以寫在單獨的文件里。但是只能 為已定義類增加 Method,而不能加入實例變量。 5、extensions可以認為是一個私有的Category。
Extension 耦合比較高,聲明可以單獨寫,但是實現必須寫在原有類的@implementation 中。可以增加 Method 和實例變量。
Extension 給人感覺更像是在編寫類時為了封裝之類的特性而設計,和類是同時編寫的。 而 category 則是在用到某一個 framework 中的類時臨時增加的特性。
Extension 的一個特性就是可以重新聲明一個實例變量,將之從 readonly 改為對內 readwrite.
使用 Extension 可以更好的封裝類,在 h 文件中能看到的都是對外的接口,其余的實例變 量和對內的@property 等都可以寫在 Extension,這樣類的結構更加清晰。
9. 字符串常用處理
1. 字符串比較
NSString *a = @“hello”; NSString *b = [NSString stringWithFormat:@hello”]; if (a == b) NSLog(@“a==b”); if ([a isEqualToString: b]) NSLog(@“a isEqualToString b”); == 比較變量中保存的數值(地址) 速度快 內容同,可能地址不同(常量區,堆區) isEqualTo 比較字符串 非常耗時
2. 字符串截取
截取字符串”20 | http://www.baidu.com”中,”|”字符前面和后面的數據,分別輸出它們。NSString * str = @"20 | http://www.baidu.com"; NSArray *array = [str componentsSeparatedByString:@"|"]; //這是分別輸出的截取后的字 符串 for (int i = 0; i<[array count]; ++i) { NSLog(@"%d=%@",i,[array objectAtIndex:i]); }
3.格式
NSString *str1 = [NSString stringWithFormat:@"a"b”]; //報錯,a”后面加b是違法的 NSString *str2 = [NSString stringWithFormat:@“a""b”]; //顯示 ab NSString *str3 = [NSString stringWithFormat:@“a\"b”]; //顯示 a”b 反斜杠轉義
10. NSArray和NSDictionary - 遍歷數組/字典的方法
數 組: for 循 環 forin enumerateObjectsUsingBlock ( 正 序 ) enumerateObjectsWithOptions:usingBlock:(多一個遍歷選項,不保證順序) 字 典: 1. for(NSString *object in [testDic allValues]) 2. for(id akey in [testDic allKeys]){ [sum appendString:[testDic objectForKey:akey]]; } 3. [testDic enumerateKeysAndObjectsUsingBlock:^(idkey,idobj,BOOL*stop) { [sum appendString:obj]; } ];
速度: 對于數組, 增強for最快,普通for和block速度差不多,增強最快是因為增強for語法會對容器里的元素的內存地址建立緩沖,遍歷的時候直接從緩沖中取元素地址而不是通過調用方 法來獲取,所以效率高.這也是使用增強for時不能在循環體中修改容器元素的原因之一(可以在 循環體中添加標記,在循環體外修改元素)
對于字典,allValues最快,allKey和block差不多,原因是allKey需要做objcetForKey的方法
11. 如何避免循環引用
兩個對象相互強引用,都無法release,解決辦法為一個使用strong,一個使用assign(weak)
12. CFSocket使用有哪幾個步驟
答:1、創建 Socket 的上下文 2、創建 Socket 3、配置要訪問的服務器信息 4、封裝服務器信息 5、連 接服務器;
13. oc幾種操作Socket的方法?
CFNetwork 、CFSocket 和 BSD Socket 。AsyncSocket
14.解析XML文件有哪幾種方式?
以 DOM 方式解析 XML 文件; 以 SAX 方式解析 XML 文件;
15.什么是沙盒模型?哪些操作是屬于私有api范疇?
某個iphone工程進行文件操作有此工程對應的指定的位置,不能逾越。 iphone沙箱模型的有四個文件夾documents,tmp,app,Library,永久數據存儲一般放 documents文件夾, 得到模擬器的路徑的可使用NSHomeDirectory()方法。 Nsuserdefaults保存 的文件在tmp文件夾里。
16.在一個對象的方法里面:self.name= “object”;和 name
=”object” 有什么不同嗎?self.name =”object”:會調用對象的setName()方法, name = “object”:會直接把object賦值給當前對象的name屬性。
17. 創建控制器、視圖的方式
創建控制器的方式
(1)通過代碼的方式加載UIViewController *controller = [[UIViewController alloc] init]; (2)通過stroyboard來加載viewController 加載storyboard中箭頭指向的viewController UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; //加載箭頭指向的viewController CZViewController *controller = [storyboard instantiateInitialViewController]; 加載storyboard中特定標示的viewController(storyboard可以有多個controller) UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; CZViewController*controller= [storyboardinstantiateViewControllerWithIdentifier:@"two"]; (3)傳統方法 1.創建Xib,并指定xib的files owner為自定義控制器類(為了能連線關聯管理IB的內容) 2. xib中要有內容,且xib中??述的控制器類的view屬性要與xib的view控件完成關聯 (關聯方 法兩種,一種是control+files owner拖線到xib中搭建的指定view控件,另一種是指定xib中的 view拖線到@interface) 3.從xib加載viewController CZViewController *controller = [[CZViewController alloc] initWithNibName:@"CZOneView" bundle:nil]; 4.bundle中取出xib內容 CZViewController *vc = [[NSBundle mainBundle] loadNibNamed:@"Two" owner:nil options:nil].lastObject;
創建視圖的方式
1.用系統的loadView方法創建控制器的視圖 2.如果指定加載某個storyboard文件做控制器的視圖,就會加載storyboard里面的描述去創建 view 3.如果指定讀取某個xib文件做控制器的視圖,就根據指定的xib文件去加載創建 4.如果有xib文件名和控制器的類名前綴(也就是去掉controller)的名字一樣的 xib文件 就 會用這個xib文件來創建控件器的視圖 例:控件器的名為 MJViewController xib文件名為 MJView.xib 如果xib文件名后有一個字不一樣就不會去根據它去創建如:MJView8.xib 5.找和控制器同名的xib文件去創建 6.如果以上都沒有就創建一個空的控制器的視圖;
18. UIWindow
是一種特殊的UIView,通常在一個程序中只會有一個UIWindow,但可以手 動創建多個UIWindow, 同時加到程序里面。UIWindow在程序中主要起到三個作用: 1、作為容器,包含app所要顯示的所有視圖 2、傳遞觸摸消息到程序中view和其他對象 3、與UIViewController協同工作,方便完成設備方向旋轉的支持
19. 簡述內存分區情況
1).代碼區:存放函數二進制代碼 2).數據區:系統運行時申請內存并初始化,系統退出時由系統釋放。存放全局變量、靜態變量、 常量 3).堆區:通過malloc等函數或new等操作符動態申請得到,需程序員手動申請和釋放 4).棧區:函數模塊內申請,函數結束時由系統自動釋放。存放局部變量、函數參數
20.隊列和棧有什么區別
隊列和棧是兩種不同的數據容器。從”數據結構”的角度看,它們都是線性結構,即數據 元素之間的關系相同。隊列是一種先進先出的數據結構,它在兩端進行操作,一端進行入隊列操作,一端進行出列隊 操作 棧是一種先進后出的數據結構,它只能在棧頂進行操作,入棧和出棧都在棧頂操作。
21 .iOS的系統架構
iOS的系統架構分為四個層次: ( 核心操作系統層 theCore OS layer ) ( 核心服務層theCore Services layer ) ( 媒體層 theMedia layer ) ( Cocoa 界面服務層 the Cocoa Touch layer )
22 .控件主要響應3種事件
1). 基于觸摸的事件 ; 2). 基于值的事件 ; 3). 基于編輯的事件。
23 .xib文件的構成分為哪3個圖標?都具有什么功能。
File’s Owner 是所有 nib 文件中的每個圖標,它表示從磁盤加載 nib 文件的對象; First Responder 就是用戶當前正在與之交互的對象; View 顯示用戶界面;完成用戶交互;是 UIView 類或其子類。
24 .簡述視圖控件器的生命周期。
loadView在controller的view為nil時調用。盡管不直接調用該方法,如手動創建自己的 視圖,那么應該覆蓋這個方法并將它們賦值給試圖控制器的 view 屬性。在C的View為nil時調 用,在編程實現View時調用。
viewDidLoad 只有在視圖控制器將其視圖載入到內存之后才調用該方法, 這是執行任何其他初始化操作的入口。在View從nib初始化的時候調用。 viewVillAppear 當試圖將要添加到窗口中并且還不可見的時候或者上層視圖移出圖層后本視 圖變成頂級視圖時調用該方法, 用于執行諸如改變視圖方向等的操作。實現該方法時確保調用 [super viewWillAppear:] viewDidAppear 當視圖添加到窗口中以后或者上層視圖移出圖層后本視圖變成頂級視圖時調用, 用于放置那些需要在視圖顯示后執行的代碼。確保調用 [super viewDidAppear:] 。 viewWillDisappear-UIViewController對象的視圖即將消失、被覆蓋或是隱藏時調用 viewDidDisappear-UIViewController對象的視圖已經消失、被覆蓋或是隱藏時調用; viewVillUnload-當內存過低時,需要釋放一些不需要使用的視圖時,即將釋放時調用; viewDidUnload 當試圖控制器從內存釋放自己的方法的時候調用,當內存過低, 釋放一些不需 要的視圖。在這里實現將retain的view release,如果是retain 的IBOutlet view 屬性則不要 在這里release,IBOutlet會負責release 。
25 .應用的生命周期 各個程序運行狀態時代理的回調
-(BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告訴代理進程啟動但還 沒進入狀態保存 -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告訴代理啟動基本完成程序準備開始運行 - (void)applicationWillResignActive:(UIApplication *)application (掛起) 1-當有電話進來或者鎖屏,這時你的應用程會掛起,在這時,UIApplicationDelegate委托會收到通知,調用 applicationWillResignActive 方法,你可以重寫這個方法,做掛起前的工作,比如關閉網絡,保存數據。 2- 當你的程序被掛起后他不會在后臺運行。 - (void)applicationDidBecomeActive:(UIApplication *)application(復原) 當程序復原時,另一個名為 applicationDidBecomeActive 委托方法會被調用,在此你可以通過之前掛起前保存的數據來恢復你的應用程序。 注意:應用程序在啟動時,在調用了 applicationDidFinishLaunching 方法之后也會調用 applicationDidBecomeActive 方法,所以你要確保你的代碼能夠分清復原與啟動,避免出現邏輯上的bug。 - (void)applicationDidEnterBackground:(UIApplication *)application 當程被序被推送到后臺的時候調用。所以要設置后臺繼續運行,則在這個函數里面設置即可 - (void)applicationWillEnterForeground:(UIApplication *)application 當程序從后臺將要重新回到前臺時候調用,這個剛好跟上面的那個方法相反。 - (void)applicationWillTerminate:(UIApplication *)application 當程序將要退出是被 調用,通常是用來保存數據和一些退出前的清理工作。
26.簡要說明一下 APP 的啟動過程,main 文件說起,main 函數中有什
么函數?作用是什么?打開程序——->執行 main 函數———>UIAPPlicationMain 函數——->初始化 UIAPPlicationMain 函數(設置代理,開啟事件循環)———>監聽系統事件—->程序結束 先執行 main 函數,main 內部會調用 UIApplicationMain 函數 UIApplicationMain 函數作用: (1)根據傳入的第三個參數創建 UIApplication 對象或它的子類對象。如果該參數為 nil,直接 使用該 UIApplication 來創建。(該參數只能傳人 UIApplication 或者是它的子類) (2)根據傳入的第四個參數創建 AppDelegate 對象,并將該對象賦值給第 1 步創建的 UIApplication 對象的 delegate 屬性。 (3)開啟一個事件循環,循環監控應用程序發生的事件。每監聽到對應的系統事件時,就會通知 AppDelegate。 main 函數作用: (1)創建 UIApplication 對象 (2)創建應用程序代理 (3)開啟時間循環,包括應用程序的循環運行,并開始處理用戶事件。
27.動畫有基本類型有哪幾種;表視圖有哪幾種基本樣式。
答:動畫有兩種基本類型:隱式動畫和顯式動畫。
28.Cocoa Touch提供了哪幾種Core Animation過渡類型?
答: Cocoa Touch 提供了 4 種 Core Animation 過渡類型,分別為:交叉淡化、推擠、顯示 和覆蓋。
29.Quatrz 2D的繪圖功能的三個核心概念是什么并簡述其作用。
答:上下文:主要用于??述圖形寫入哪里; 路徑:是在圖層上繪制的內容; 狀態:用于保存配置變換的值、填充和輪廓, alpha 值等。
30.Phone OS主要提供了幾種播放音頻的方法?
答: SystemSound Services、AVAudioPlayer、Audio Queue Services、OpenAL
31.使用AVAudioPlayer類調用哪個框架、使用步驟?
答: AVFoundation.framework 步驟:配置 AVAudioPlayer 對象; 實現 AVAudioPlayer 類的委托方法; 控制 AVAudioPlayer 類的對象; 監控音量水平; 回放進度和拖拽播放。
32.有哪幾種手勢通知方法、寫清楚方法名?
-(void)touchesBegan:(NSSet*)touchedwithEvent:(UIEvent*)event; -(void)touchesMoved:(NSSet*)touched withEvent:(UIEvent*)event; -(void)touchesEnded:(NSSet*)touchedwithEvent:(UIEvent*)event; -(void)touchesCanceled:(NSSet*)touchedwithEvent:(UIEvent*)event;
33.ViewController的didReceiveMemoryWarning怎么被調用
答:[super didReceiveMemoryWarning];
34.用預處理指令#define聲明一個常數,用以表明1年中有多少秒(忽
略閏年問題)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在這想看到幾件事情: #define 語法的基本知識(例如:不能以分號結束,括號的使用,等等) 懂得預處理器將為你計算常數表達式的值,因此,直接寫出你是如何計算一年中有多少秒而不 是計算出實際的值,是更清晰而沒有代價的。 意識到這個表達式將使一個16位機的整型數溢出-因此要用到長整型符號L,告訴編譯器這個常 數是的長整型數。 如果你在你的表達式中用到UL(表示無符號長整型),那么你有了一個好的起點。記住,第一印 象很重要。
35.寫一個”標準"宏MIN ,這個宏輸入兩個參數并返回較小的一個
#define MIN(A,B) ((A) <= (B) ? (A) : (B)) 這個測試是為下面的目的而設的: 標識#define在宏中應用的基本知識。這是很重要的,因為直到嵌入(inline)操作符變為標準C 的一部分,宏是方便產生嵌入代碼的唯一方法, 對于嵌入式系統來說,為了能達到要求的性能,嵌入代碼經常是必須的方法。 三重條件操作符的知識。這個操作符存在C語言中的原因是它使得編譯器能產生比 if-then-else 更優化的代碼,了解這個用法是很重要的。 懂得在宏中小心地把參數用括號括起來 我也用這個問題開始討論宏的副作用,例如:當你寫下面的代碼時會發生什么事? least = MIN(*p++, b); least = MIN(*p++, b); 結果是: ((*p++) <= (b) ? (*p++) : (*p++)) ((*p++) <= (b) ? (*p++) : (*p++)) 這個表達式會產生副作用,指針p會作三次++自增操作。
36.關鍵字const有什么含意?修飾類呢?static的作用,用于類呢?還
有externc的作用,const 意味著"只讀",下面的聲明都是什么意思?const int a; a是一個常整型數 int const a; a是一個常整型數 const int *a; 一個指向常整型數的指針(也就是,整型數是不可修改的,但指針可以)。 int * const a; 一個指向整型數的常指針(也就是說,指針指向的整型數是可以修改的,但指針 是不可修改的)。 int const * a const; 最后一個意味著a是一個指向常整型數的常指針(也就是說,指針指向的整型數是不可修改的, 同時指針也是不可修改的)。
結論:
關鍵字const的作用是為給讀你代碼的人傳達非常有用的信息,實際上,聲明一個參數為常量是 為了告訴了用戶這個參數的應用目的。如果你曾花很多時間清理其它人留下的垃圾,你就會很快學會感謝這點多余的信息。(當然,懂 得用const的程序員很少會留下的垃圾讓別人來清理的) 通過給優化器一些附加的信息,使用 關鍵字const也許能產生更緊湊的代碼。合理地使用關鍵字const可以使編譯器很自然地保護那 些不希望被改變的參數,防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現。
1).欲阻止一個變量被改變,可以使用 const 關鍵字。在定義該 const 變量時,通常需要對它 進行初始化,因為以后就沒有機會再去改變它了; 2).對指針來說,可以指定指針本身為 const,也可以指定指針所指的數據為 const,或二者同 時指定為 const; 3).在一個函數聲明中,const 可以修飾形參,表明它是一個輸入參數,在函數內部不能改變其 值; 4).對于類的成員函數,若指定其為 const 類型,則表明其是一個常函數,不能修改類的成員變量; 5).對于類的成員函數,有時候必須指定其返回值為 const 類型,以使得其返回值不為“左值”。
37.關鍵字volatile有什么含意?并給出三個不同的例子。
答:一個定義為 volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去 假設這個變量的值了。精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這 個變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個例子: 并行設備的硬件寄存器(如:狀態寄存器) 一個中斷服務子程序中會訪問到的非自動變量(Non-automatic variables) 多線程應用中被幾個任務共享的變量
38.一個參數既可以是const還可以是volatile嗎?一個指針可以是
volatile嗎?答:1).是的。一個例子是只讀的狀態寄存器。它是volatile因為它可能被意想不到地改變。它 是const因為程序不應該試圖去修改它。 2).是的。盡管這并不很常見。一個例子是當一個中服務子程序修該一個指向一個buffer的指針時。
39.static 關鍵字的作用
1).函數體內 static 變量的作用范圍為該函數體,不同于 auto 變量,該變量的內存只被分配 一次, 因此其值在下次調用時仍維持上次的值; 2).在模塊內的 static 全局變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問; 3).在模塊內的 static 函數只可被這一模塊內的其它函數調用,這個函數的使用范圍被限制在 聲明 它的模塊內; 4).在類中的 static 成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝; 5).在類中的 static 成員函數屬于整個類所擁有,這個函數不接收 this 指針,因而只能訪問 類的static 成員變量。
40.列舉幾種進程的同步機制,并比較其優缺點。
答: 原子操作 信號量機制 自旋鎖 管程,會合,分布式系統
41.進程之間通信的途徑
答:共享存儲系統消息傳遞系統管道:以文件系統為基礎
42.進程死鎖的原因
答:資源競爭及進程推進順序非法
43.死鎖的4個必要條件
答:互斥、請求保持、不可剝奪、環路
44.死鎖的處理
答:鴕鳥策略、預防策略、避免策略、檢測與解除死鎖
45.cocoa touch框架
答:iPhone OS 應用程序的基礎 Cocoa Touch 框架重用了許多 Mac 系統的成熟模式,但是它 更多地專注于觸摸的接口和優化。UIKit 為您??供了在 iPhone OS 上實現圖形,事件驅動程序的基本工具,其建立在和 Mac OS X 中一樣的 Foundation 框架上,包括文件處理,網絡,字符串操作等。
Cocoa Touch 具有和 iPhone 用戶接口一致的特殊設計。有了 UIKit,您可以使用 iPhone OS 上 的獨特的圖形接口控件,按鈕,以及全屏視圖的功能,您還可以使用加速儀和多點觸摸手勢來 控制您的應用。
各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了創建世界一流 iPhone 應用程序需要的所 有框架,從三維圖形,到專業音效,甚至??供設備訪問 API 以控制攝像頭,或通過 GPS 獲知 當前位置。
Cocoa Touch 既包含只需要幾行代碼就可以完成全部任務的強大的 Objective-C 框架,也在需 要時??供基礎的 C 語言 API 來直接訪問系統。這些框架包括:
Core Animation:通過 Core Animation,您就可以通過一個基于組合獨立圖層的簡單的編程模 型來創建豐富的用戶體驗。
Core Audio:Core Audio 是播放,處理和錄制音頻的專業技術,能夠輕松為您的應用程序添加強大的音頻功能。
Core Data:??供了一個面向對象的數據管理解決方案,它易于使用和理解,甚至可處理任何應 用或大或小的數據模型。
功能列表:框架分類
下面是 Cocoa Touch 中一小部分可用的框架: 音頻和視頻:Core Audio ,OpenAL ,Media Library ,AV Foundation 數據管理 :Core Data ,SQLite 圖形和動畫 :Core Animation ,OpenGL ES ,Quartz 2D 網絡:Bonjour ,WebKit ,BSD Sockets 用戶應用:Address Book ,Core Location ,Map Kit ,Store Kit
46.自動釋放池是什么,如何工作
答:當您向一個對象發送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新 的自動釋放.它仍然是個正當的對象,因此自動釋放池定義的作用域內的其它對象可以向它發送 消息。當程序執行到作用域結束的位置時,自動釋放池就會被釋放,池中的所有對象也就被釋 放。
47.sprintf,strcpy,memcpy使用上有什么要注意的地方。
1). sprintf是格式化函數。將一段數據通過特定的格式,格式化到一個字符串緩沖區中去。 sprintf格式化的函數的長度不可控,有可能格式化后的字符串會超出緩沖區的大小,造成溢出。
2).strcpy是一個字符串拷貝的函數,它的函數原型為strcpy(char *dst, const char *src
將src開始的一段字符串拷貝到dst開始的內存中去,結束的標志符號為 ‘\0',由于拷貝的長 度不是由我們自己控制的,所以這個字符串拷貝很容易出錯。3). memcpy是具備字符串拷貝功能的函數,這是一個內存拷貝函數,它的函數原型為 memcpy(char dst, const char src, unsigned int len);將長度為len的一段內存,從src 拷貝到dst中去,這個函數的長度可控。但是會有內存疊加的問題。
48.你了解svn,cvs等版本控制工具么?
答: 版本控制 svn,cvs 是兩種版控制的器,需要配套相關的svn,cvs服務器。scm是xcode里配 置版本控制的地方。版本控制的原理就是a和b同時開發一個項目,a寫完當天的代碼之后把代碼 ??交給服務器,b要做的時候先從服務器得到最新版本,就可以接著做。 如果a和b都要??交給 服務器,并且同時修改了同一個方法,就會產生代碼沖突,如果a先??交,那么b??交時,服務器可以??示沖突的代碼,b可以清晰的看到,并做出相應的修改或融合后再??交到服務器。
49.什么是push
答: 客戶端程序留下后門端口,客戶端總是監聽針對這個后門的請求,于是 服務器可以主動 像這個端口推送消息。
50.靜態鏈接庫
答:此為.a文件,相當于java里的jar包,把一些類編譯到一個包中,在不同的工程中如果導入 此文件就可以使用里面的類,具體使用依然是#import “ xx.h”。
51.三大特性
1.封裝_點語法
(1)本質 //以下代碼有什么問題 - (void)setName:(NSString *)name { self.name = name; } - (NSString *)name { return self.name; } (2)點語法的本質是調用類的getter方法和setter方法,如果類中沒有getter方法和setter方法 就不能使用點語法。
2.繼承
(1)如何實現多重繼承消息轉發 forwardingTargetForSelector methodSignatureForSelector delegate和protocol 類別
3.多態
1> 什么是多態
多態:不同對象以自己的方式響應相同的消息的能力叫做多態。子類指針可以賦值給父類。 由于每個類都屬于該類的名字空間,這使得多態稱為可能。類定義中的名字和類定義外的名字并不會沖突。類的實例變量和類方法有如下特點:? 和C語言中結構體中的數據成員一樣,類的實例變量也位于該類獨有的名字空間。
? 類方法也同樣位于該類獨有的名字空間。與C語言中的方法名不同,類的方法名并不是一個全 局符號。一個類中的方法名不會和其他類中同樣的方法名沖突。兩個完全不同的類可以 實現同一個方法。
方法名是對象接口的一部分。對象收到的消息的名字就是調用的方法的名字。因為不同的對象 可以有同名的方法,所以對象必須能理解消息的含義。同樣的消息發給不同的對象,導致的操 作并不相同。
多態的主要好處就是簡化了編程接口。它容許在類和類之間重用一些習慣性的命名,而不用 為每一個新加的函數命名一個新名字。這樣,編程接口就是一些抽象的行為的集合,從而和實 現接口的類區分開來。
Objective-C支持方法名的多態,但不支持參數和操作符的多態。
2> OC中如何實現多態
在Objective-C中是通過一個叫做selector的選取器實現的。在Objective-C中,selector有兩個意思, 當用在給對象的源碼消息時,用來指方法的名字。它也指那個在源碼編譯后代替 方法名的唯一的標識符。 編譯后的選擇器的類型是SEL有同樣名字的方法、也有同樣的選擇器。 你可以使用選擇器來調用一個對象的方法。選取器有以下特點:
* 所有同名的方法擁有同樣的選取器 * 所有的選取器都是不一樣的
(1) SEL和@selector
選擇器的類型是 SEL。@selector指示符用來引用選擇器,返回類型是SEL。例如:SEL responseSEL; responseSEL = @selector(loadDataForTableView:); 可以通過字符串來得到選取器, 例如:responseSEL = NSSelectorFromString(@"loadDataForTableView:"); 也可以通過反向轉換,得到方法名, 例如:NSString *methodName = NSStringFromSelector(responseSEL);
(2) 方法和選取器
選取器確定的是方法名,而不是方法實現。這是多態性和動態綁定的基礎,它使得向不同 類對象發送相同的消息成為現實;否則,發送消息和標準C中調用方法就沒有區別,也就不可能 支持多態性和動態綁定。另外,同一個類的同名類方法和實例方法擁有相同的選取器。
(3) 方法返回值和參數類型
消息機制通過選取器找到方法的返回值類型和參數類型,因此,動態綁定(例:向id定義 的對象發送消息)需要同名方法的實現擁有相同返回值類型和相同的參數類型;否則,運行時 可能出現找不到對應方法的錯誤。一個例外,雖然同名類方法和實例方法擁有相同的選取器,但是它們可以有不同的參數 類型和返回值類型。
3> 動態綁定
52. OC的優缺點。
答: 優點:1).Cateogies 2).Posing 3).動態識別 4).指標計算 5).彈性訊息傳遞 6).不是一個過度復雜的C衍生語言 7).Objective-C 與 C++ 可混合編程 缺點: 1).不支持命名空間 2).不支持運算符重載 3).不支持多重繼承 4).使用動態運行 時類型,所有的方法都是函數調用,所以很多編譯時優化方法都用不到。(如內聯函數等),性 能低劣。 對于命名沖突可以使用長命名法或特殊前綴解決, 如果是引入的第三方庫之間的命名沖突, 可以使用link命令及flag解決沖突
53. oc中可修改和不可以修改類型。
答:可修改不可修改的集合類,這個我個人簡單理解就是可動態添加修改和不可動態添加修改 一樣。比如NSArray和NSMutableArray,前者在初始化后的內存控件就是固定不可變的,后者可 以添加等,可以動態申請新的內存空間。
54. 我們說的oc是動態運行時語言是什么意思?
答:多態。主要是將數據類型的確定由編譯時,推遲到了運行時。這個問題其實淺涉及到兩個 概念,運行時和多態。
簡單來說,運行時機制使我們直到運行時才去決定一個對象的類別,以及調用該類別對象指定 方法。
多態:不同對象以自己的方式響應相同的消息的能力叫做多態。
意思就是假設生物類(life)都用有一個相同的方法-eat。那人類屬于生物,豬也屬于生物,都 繼承了life后,實現各自的eat,但是調用是我們只需調用各自的eat方法。也就是不同的對象 以自己的方式響應了相同的消息(響應了eat這個選擇器)。因此也可以說,運行時機制是多態的 基礎?~~~
55. 什么是謂詞?
答:謂詞是通過NSPredicate,是通過給定的邏輯條件作為約束條件,完成對數據的篩選。 predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n]; a = [customers filteredArrayUsingPredicate:predicate]; predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n]; a = [customers filteredArrayUsingPredicate:predicate];
56. 簡單介紹下NSURLConnection類及+sendSynchronousRequest:returningResponse:error:與 –
initWithRequest:delegate:兩個方法的區別?答 :NSURLConnection 主 要 用 于 網 絡 訪 問 , 其 中 + sendSynchronousRequest:returningResponse:error:是同步訪問數據 當前線程會阻塞,并 等待request的返回的response。 而– initWithRequest:delegate:使用的是異步加載,當其完 成網絡訪問后, 會通過delegate回到主線程,并其委托的對象。
57.談談OC的內存管理方式及過程?
答: 1).當你使用new,alloc和copy方法創建一個對象時,該對象的保留計數器值為1. 當你不再 使用該對象時,你要負責向該對象發送一條release或autorelease消息. 這樣,該對象將在使用 壽命結束時被銷毀. 2).當你通過任何其他方法獲得一個對象時,則假設該對象的保留計數器值為1, 而且已經被設置 為自動釋放,你不需要執行任何操作來確保該對象被清理. 如果你打算在一段時間內擁有該對象, 則需要保留它并確保在操作完成時釋放它. 3).如果你保留了某個對象,你需要(最終)釋放或自動釋放該對象.必須保持retain方法和 release方法的使用次數相等.
58.OC有私有方法嗎?私有變量呢?
objective-c – 類里面的方法只有兩種, 靜態方法和實例方法. 這似乎就不是完整的面向 對象了,按照OO的原則就是一個對象只暴露有用的東西. 如果沒有了私有方法的話, 對于一些 小范圍的代碼重用就不那么順手了. 在類里面聲名一個私有方法
@interface Controller : NSObject { NSString *something; } + (void)thisIsAStaticMethod; – (void)thisIsAnInstanceMethod; @end @interface Controller (private) - (void)thisIsAPrivateMethod; @end @private可以用來修飾私有變量 在Objective‐C中,所有實例變量默認都是私有的,所有實例方法默認都是公有的
59.事件傳遞&響應者鏈
事件響應鏈:
包括點擊事件,畫面刷新事件等。在視圖棧內從上至下,或者從下之上傳播。可 以說點事件的分發,傳遞以及處理。
事件的產生和傳遞過程:
1.當觸摸事件發生時,壓力轉為電信號,iOS系統將產生UIEvent對象,記錄事件產生的時間 和類型,然后系統將事件加入到一個由UIApplication管理的事件隊列中。 2.UIApplication 會從事件隊列中取出最前面的事件,并將事件分發下去以便處理,通常 會先發送事件給應用程序的主窗口(keyWindow) 3.主窗口會在視圖層次結構中找到一個最合適的視圖來處理觸摸事件 4.找到合適的視圖控件后,就會調用視圖控件的 touches 方法來作事件的具體處理: touchesBegin... touchesMoved...touchesEnded 等 5.這些 touches 方法默認的做法是將事件順著響應者鏈條向上傳遞,將事件叫個上一個相 應者進行處理 一般事件的傳遞是從父控件傳遞到子控件的
如果父控件接受不到觸摸事件,那么子控件就不可能接收到觸摸事件 UIView 不能接收觸摸事 件的三種情況:
1.不接受用戶交互:userInteractionEnabled = NO; 2.隱藏:hidden = YES; 3.透明:alpha = 0.0~0.01 用戶的觸摸事件首先會由系統截獲,進行包裝處理等。 然后遞歸遍歷所有的 view,進行碰觸測試(hitTest),直到找到可以處理事件的 view。 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event; // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; // default returns YES if point is in bounds 大致的過程 application –> window –> root view –>......–>lowest view
響應者鏈
響應者鏈條:其實就是很多響應者對象(繼承自 UIResponder 的對象)一起組合起來的鏈條稱之為響應者鏈條
一般默認做法是控件將事件順著響應者鏈條向上傳遞,將事件交給上一個響應者進行處理。 那么如何判斷當前響應者的上一個響應者是誰呢?有以下兩個規則:
1.判斷當前是否是控制器的 View,如果是控制器的 View,上一個響應者就是控制器 2.如果不是控制器的 View,上一個響應者就是父控件
當有 view 能夠處理觸摸事件后,開始響應事件。 系統會調用 view 的以下方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 可以多對象共同響應事件。只需要在以上方法重載中調用 super 的方法。 大致的過程 initial view –> super view –> .....–> view controller –> window –> Application
需要特別注意的一點是,傳遞鏈中時沒有 controller 的,因為 controller 本身不具有大 小的概念。但是響應鏈中是有 controller 的,因為 controller 繼承自 UIResponder。
UIApplication–>UIWindow–>遞歸找到最合適處理的控件–>控件調用 touches 方法–>判斷 是 否實現 touches 方法–>沒有實現默認會將事件傳遞給上一個響應者–>找到上一個響應者 –>找不到方法作廢
PS:利用響應者鏈條我們可以通過調用 touches 的 super 方法,讓多個響應者同時響應該事件。
60.frame和bounds有什么不同?
答: frame指的是:該view在父view坐標系統中的位置和大小。(參照點是父親的坐標系統) bounds指的是:該view在本身坐標系統中 的位置和大小。(參照點是本身坐標系統)
61.方法和選擇器有何不同?
答:selector是一個方法的名字,method是一個組合體,包含了名字和實現,詳情可以看apple 文檔。
62.什么是延遲加載?
答:懶漢模式,只在用到的時候才去初始化,也可以理解成延時加載。
我覺得最好也最簡單的一個列子就是tableView中圖片的加載顯示了。一個延時載,避免內存過 高,一個異步加載,避免線程堵塞。
63.是否在一個視圖控制器中嵌入兩個tableview控制器?
答:一個視圖控制只??供了一個View視圖,理論上一個tableViewController也不能放吧,只能 說可以嵌入一個tableview視圖。當然,題目本身也有歧義,如果不是我們定性思維認為的 UIViewController,而是宏觀的表示視圖控制者,那我們倒是可以把其看成一個視圖控制者, 它可以控制多個視圖控制器,比如TabbarController那樣的感覺。
64.一個tableView是否可以關聯兩個不同的數據源?你會怎么處理?
答:首先我們從代碼來看,數據源如何關聯上的,其實是在數據源關聯的代理方法里實現的。 因此我們并不關心如何去關聯他,他怎么關聯上,方法只是讓我返回根據自己的需要去設置如 相關的數據源。因此,我覺得可以設置多個數據源啊,但是有個問題是,你這是想干嘛呢?想讓列表如何顯示, 不同的數據源分區塊顯示?
65.什么時候使用NSMutableArray,什么時候使用NSArray?
答:當數組在程序運行時,需要不斷變化的,使用NSMutableArray,當數組在初始化后,便不 再改變的,使用NSArray。需要指出的是,使用NSArray只表明的是該數組在運行時不發生改變, 即不能往NSAarry的數組里新增和刪除元素,但不表明其數組內的元素的內容不能發生改變。 NSArray是線程安全的,NSMutableArray不是線程安全的,多線程使用到NSMutableArray需要注 意。
66.在應用中可以創建多少autorelease對象,是否有限制?
答案:無
67.如果我們不創建內存池,是否有內存池??供給我們?
答:界面線程維護著自己的內存池,用戶自己創建的數據線程,則需要創建該線程的內存池
68.什么時候需要在程序中創建內存池?
答:用戶自己創建的數據線程,則需要創建該線程的內存池
69.類NSObject的那些方法經常被使用?
答:NSObject是Objetive-C的基類,其由NSObject類及一系列協議構成。其中類方法alloc、class、 description 對象方法init、dealloc、– performSelector:withObject:afterDelay:等經常 被使用
70.什么是簡便構造方法?
答:簡便構造方法一般由CocoaTouch框架??供,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt: + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
Foundation下大部分類均有簡便構造方法,我們可以通過簡便構造方法,獲得系統給我們創建 好的對象,并且不需要手動釋放。
71.如何使用Xcode設計通用應用?
答:使用MVC模式設計應用,其中Model層完成脫離界面,即在Model層,其是可運行在任何設備 上,在controller層,根據iPhone與iPad(獨有UISplitViewController)的不同特點選擇不同的 viewController對象。在View層,可根據現實要求,來設計,其中以xib文件設計時,其設置其 為universal。
72.UIView的動畫效果有那些?
UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUp UIViewAnimationOptionTransitionCurlDown UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUp UIViewAnimationOptionTransitionCurlDown
73. C和OC如何混用?
1).obj-c的編譯器處理后綴為m的文件時,可以識別obj-c和c的代碼,處理mm文件可以識別 obj-c,c,c++代碼,但cpp文件必須只能用c/c++代碼,而且cpp文件include的頭文件中,也不能 出現obj-c的代碼,因為cpp只是cpp
2).在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是問題
3).在cpp中混用obj-c其實就是使用obj-c編寫的模塊是我們想要的。
如果模塊以類實現,那么要按照cpp class的標準寫類的定義,頭文件中不能出現obj-c的東西, 包括#import cocoa的。實現文件中,即類的實現代碼中可以使用obj-c的東西,可以import, 只是后綴是mm。
如果模塊以函數實現,那么頭文件要按c的格式聲明函數,實現文件中,c++函數內部可以用obj-c, 但后綴還是mm或m。
總結:只要cpp文件和cpp include的文件中不包含obj-c的東西就可以用了,cpp混用obj-c的關 鍵是使用接口,而不能直接使用 實現代 碼,實際上cpp混用的是obj-c編譯后的o文件,這個東 西其實是無差別的,所以可以用。obj-c的編譯器支持cpp。
74. 深拷貝與前拷貝區別?
1>深拷貝與前拷貝區別:
淺拷貝:是指針拷貝,對一個對象進行淺拷貝,相當于對指向對象 的指>針進行復制,產生一個新的指向這個對象的指針, 那么就是有兩個指針指向同一個對象, 這個對象銷毀后兩個指針都應該置空。 深拷貝:是對一個對象進行拷貝,相當于對對象進行復制, 產生一個新的對象,那么就有兩個指針分別指向兩個對象。 當一個對象改變或者被銷毀后拷貝 出來的新的對象不受影響。
實現深拷貝需要實現 NSCoying 協議,實現- (id)copyWithZone:(NSZone *)zone 方法。當 對一個 property 屬性含有 copy 修飾符的時候,在進行賦值操作的時候實際上就是調用這個方 法。
父類實現深拷貝之后,子類只要重寫 copyWithZone 方法,在方法內部調用父類的 copyWithZone 方法,之后實現自己的屬性的處理
父類沒有實現深拷貝,子類除了需要對自己的屬性進行處理,還要對父類的屬性進行處理
淺拷貝:本質上沒有產生新對象 深拷貝:產生了新對象
2> 什么是深拷貝淺拷貝
對于非容器類對象,不可變對象進行copy操作為淺拷貝,引用計數器加1,其他三種為深拷貝對于容器類對象,基本和非容器類對象一致,但注意其深拷貝是對象本身是對象復制,其中元素 仍為指針復制,系統將initWithArray方法歸為了元素深拷貝,但其實如果元素為不可變元素,仍 為指針復制,使用歸解檔可以實現真正的深拷貝,元素也是對象拷貝
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: array]];
3> 字符串什么時候使用copy,strong
屬性引用的對象由兩種情況,可變和不可變字符串 引用對象不可變情況下,copy和strong一樣,copy為淺拷貝 引用對象可變情況下,如果希望屬性跟隨引用對象變化,使用strong,希望不跟隨變化使用copy
4> 字符串所在內存區域
@“abc” 常量區 stringwithformat 堆區5> mutablecopy和copy @property(copy) NSMutableArray *arr;這樣寫有什么 問題
mutablecopy返回可變對象,copy返回不可變對象
6> 如何讓自定義類可以使用copy修飾符
實現<NSCopying>協議,重寫copyWithZone方法
75. id、NSObject、instancetype 的區別?
Id 聲明的對象具有運行時的特性,即可以指向任意類型的 Objcetive-C 的對象; id 是一個 objc_object 結構體指針,定義是 typedef struct objc_object *id id 可以理解為指向對象的指針。所有 oc 的對象 id 都可以指向,編譯器不會做類型檢查, id 調用任何存在的方法都不會在編譯階段報錯,當然如果這個 id 指向的對象沒有這個方法, 該崩潰還是會崩潰的。 NSObject *指向的必須是 NSObject 的子類,調用的也只能是 NSObjec 里面的方法否則就要 做強制類型轉換。 不是所有的 OC 對象都是 NSObject 的子類,還有一些繼承自 NSProxy。NSObject *可指向 的類型是 id 的子集 instancetype 只能返回值,編譯時判斷真實類型,不符合發警告
76.對于語句 NSString obj = [[NSData alloc] init]; obj 在編譯時
和運行時分別時什么類型的對象?編譯時是 NSString 的類型;運行時是 NSData 類型的對象
77.寫 一 個 setter 方 法 用 于 完 成 @property (nonatomic,retain)NSString name,寫一個setter方法用于完成 @property(nonatomic,copy)NSString name
- (void)setName:(NSString*)str { if (_name != str) { [_name release]; _name = [str retain]; } } - (void)setName:(NSString *)str { if (_name != str) { [_name release]; _name = [str copy]; } }
78.常見的Objective-C的數據類型有那些, 和C的基本數據類型有什
么區別?如:NSInteger和int
答:Objective-C的數據類型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等, 這些都是class,創建后便是對象,而C語言的基本數據類型int,只是一定字節的內存空間,用 于存放數值;NSInteger是基本數據類型Int或者Long的別名(NSInteger的定義typedef long NSInteger),NSInteger表示當前cpu下整型所占最大字節,不同CPU的long型所占字節不 同,32位int4 long4,64位int4,long8
79.OC如何對內存管理的,說說你的看法和解決方法?
Objective-C的內存管理主要有三種方式ARC(自動內存計數)、手動內存計數、內存池。
1). (Garbage Collection)自動內存計數:這種方式和java類似,在你的程序的執行過程中。 始終有一個高人在背后準確地幫你收拾垃圾,你不用考慮它什么時候開始工作,怎樣工作。你 只需要明白,我申請了一段內存空間,當我不再使用從而這段內存成為垃圾的時候,我就徹底 的把它忘記掉,反正那個高人會幫我收拾垃圾。遺憾的是,那個高人需要消耗一定的資源,在 攜帶設備里面,資源是緊俏商品所以iPhone不支持這個功能。所以“Garbage Collection”不 是本入門指南的范圍,對“Garbage Collection”內部機制感興趣的同學可以參考一些其他的 資料,不過說老實話“Garbage Collection”不大適合適初學者研究。
解決: 通過alloc – initial方式創建的, 創建后引用計數+1, 此后每retain一次引用計數+1, 那么在程序中做相應次數的release就好了.
2). (Reference Counted)手動內存計數:就是說,從一段內存被申請之后,就存在一個變量用 于保存這段內存被使用的次數,我們暫時把它稱為計數器,當計數器變為0的時候,那么就是釋 放這段內存的時候。比如說,當在程序A里面一段內存被成功申請完成之后,那么這個計數器就 從0變成1(我們把這個過程叫做alloc),然后程序B也需要使用這個內存,那么計數器就從1變成 了2(我們把這個過程叫做retain)。緊接著程序A不再需要這段內存了,那么程序A就把這個計數 器減1(我們把這個過程叫做release);程序B也不再需要這段內存的時候,那么也把計數器減1(這個過程還是release)。當系統(也就是Foundation)發現這個計數器變 成員了0,那么就會 調用內存回收程序把這段內存回收(我們把這個過程叫做dealloc)。順便??一句,如果沒有 Foundation,那么維護計數器,釋放內存等等工作需要你手工來完成。
解決:一般是由類的靜態方法創建的, 函數名中不會出現alloc或init字樣, 如[NSString string]和[NSArray arrayWithObject:], 創建后引用計數+0, 在函數出棧后釋放, 即相當于 一個棧上的局部變量. 當然也可以通過retain延長對象的生存期.
3). (NSAutoRealeasePool)內存池:可以通過創建和釋放內存池控制內存申請和回收的時機.
解決:是由autorelease加入系統內存池, 內存池是可以嵌套的, 每個內存池都需要有一個創建 釋放對, 就像main函數中寫的一樣. 使用也很簡單, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即將一個NSString對象加入到最內 層的系統內存池, 當我們釋放這個內存池時, 其中的對象都會被釋放.
80.原子(atomic)跟非原子(non-atomic)屬性有什么區別??
1). atomic??供多線程安全。是防止在寫未完成的時候被另外一個線程讀取,造成數據錯誤2). non-atomic:在自己管理內存的環境中,解析的訪問器保留并自動釋放返回的值,如果指定 了 nonatomic ,那么訪問器只是簡單地返回這個值。
原子屬性采用的是"多讀單寫"機制的多線程策略 "多讀單寫"縮小了鎖范圍,比互斥鎖的性能好 規定只在主線程更新UI,就是因為如果在多線程中更新,就需要給UI對象加鎖,防止資源搶占寫 入錯誤,但是這樣會降低UI交互的性能, 所以ios設計讓所有UI對象都是非線程安全的(不加鎖), 并規定只在主線程中更新UI,規避多線程搶占資源問題
81.看下面的程序,第一個NSLog會輸出什么?這時str的retainCount是
多少?第二個和第三個呢? 為什么?NSMutableArray* ary = [[NSMutableArray array] retain]; NSString *str = [NSString stringWithFormat:@"test"]; [str retain]; [ary addObject:str]; NSLog(@”%@%d”,str,[str retainCount]); [str retain]; [str release]; [str release]; NSLog(@”%@%d”,str,[str retainCount]); [aryremoveAllObjects]; NSLog(@”%@%d”,str,[str retainCount]); NSMutableArray* ary = [[NSMutableArray array] retain]; NSString *str = [NSString stringWithFormat:@"test"]; [str retain]; [aryaddObject:str]; NSLog(@”%@%d”,str,[str retainCount]); [str retain]; [str release]; [str release]; NSLog(@”%@%d”,str,[str retainCount]); [aryremoveAllObjects]; NSLog(@”%@%d”,str,[str retainCount]); str的retainCount創建+1, retain+1,加入數組自動+1 3 retain+1,release-1,release-1 2 數組刪除所有對象,所有數組內的對象自動-1 1
82.內存管理的幾條原則時什么?按照默認法則.那些關鍵字生成的對
象需要手動釋放?在和property結合的時候怎樣有效的避免內存泄露?誰申請,誰釋放 遵循Cocoa Touch的使用原則; 內存管理主要要避免“過早釋放”和“內存泄漏”,對于“過早釋放”需要注意@property設置 特性時,一定要用對特性關鍵字,對于“內存泄漏”,一定要申請了要負責釋放,要細心。 關鍵字alloc 或new 生成的對象需要手動釋放; 設置正確的property屬性,對于retain需要在合適的地方釋放,
83如何對iOS設備進行性能測試?
答: Profile-> Instruments ->Time Profiler