1.寫一個NSString類的實現+(id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
+ (id) stringWithCString: (c*****t char*)nullTerminatedCString
encoding: (NSStringEncoding)encoding
{
NSString *obj;
obj = [self allocWithZone: NSDefaultMallocZone()];
obj = [obj initWithCString: nullTerminatedCString encoding: encoding];
return AUTORELEASE(obj);
}
2static關鍵字的作用:
(1)函數體內static變數的作用範圍為該函數體,不同於auto變數,該變數的記憶體只被分配一次,
因此其值在下次調用時仍維持上次的值;
(2)在模組內的static全域變數可以被模組內所用函數訪問,但不能被模組外其它函數訪問;
(3)在模組內的static函數只可被這一模組內的其它函數調用,這個函數的使用範圍被限制在聲明
它的模組內;
(4)在類中的static成員變數屬於整個類所擁有,對類的所有對象只有一份拷貝;
(5)在類中的static成員函數屬於整個類所擁有,這個函數不接收this指標,因而只能訪問類的static成員變數。
3線程與進程的區別和聯絡?
進程和線程都是由作業系統所體會的程式啟動並執行基本單元,系統利用該基本單元實現系統對應用的並發性。
程和線程的主要差別在於它們是不同的作業系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變數,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程式要比多線程的程式健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共用某些變數的並行作業,只能用線程,不能用進程。
4堆和棧的區別
管理方式:對於棧來講,是由編譯器自動管理,無需我們手工控制;對於堆來說,釋放工作由程式員控制,容易產生memory leak。
申請大小:
棧:在Windows下,棧是向低地址擴充的資料結構,是一塊連續的記憶體的地區。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時間就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴充的資料結構,是不連續的記憶體地區。這是由於系統是用鏈表來儲存的空閑記憶體位址的,自然是不連續的,而鏈表的遍曆方向是由低地址向高地址。堆的大小受限於電腦系統中有效虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。
片段問題:對於堆來講,頻繁的new/delete勢必會造成記憶體空間的不連續,從而造成大量的片段,使程式效率降低。對於棧來講,則不會存在這個問題,因為棧是先進後出的隊列,他們是如此的一一對應,以至於永遠都不可能有一個記憶體塊從棧中間彈出
分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如局部變數的分配。動態分配由alloca函數進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。
分配效率:棧是機器系統提供的資料結構,電腦會在底層對棧提供支援:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的。
5什麼是鍵-值,鍵路徑是什麼
模型的性質是通過一個簡單的鍵(通常是個字串)來指定的。視圖和控制器通過鍵來尋找相應的屬性值。在一個給定的實體中,同一個屬性的所有值具有相同的資料類型。鍵-值編碼技術用於進行這樣的尋找—它是一種間接訪問對象屬性的機制。
鍵路徑是一個由用點作分隔字元的鍵組成的字串,用於指定一個串連在一起的對象性質序列。第一個鍵的
性質是由先前的性質決定的,接下來每個鍵的值也是相對於其前面的性質。鍵路徑使您可以以獨立於模型
實現的方式指定相關對象的性質。通過鍵路徑,您可以指定對象圖中的一個任意深度的路徑,使其指向相
關對象的特定屬性。
6目標-動作機制
目標是動作訊息的接收者。一個控制項,或者更為常見的是它的單元,以插座變數(參見"插座變數"部分)
的形式保有其動作訊息的目標。
動作是控制項發送給目標的訊息,或者從目標的角度看,它是目標為了響應動作而實現的方法。
程式需要某些機制來進行事件和指令的翻譯。這個機制就是目標-動作機制。
7objc的記憶體管理
??如果您通過分配和初始化(比如[[MyClass alloc] init])的方式來建立對象,您就擁
有這個對象,需要負責該對象的釋放。這個規則在使用NSObject的便利方法new時也同樣適用。
??如果您拷貝一個對象,您也擁有拷貝得到的對象,需要負責該對象的釋放。
??如果您保持一個對象,您就部分擁有這個對象,需要在不再使用時釋放該對象。
反過來,
??如果您從其它對象那裡接收到一個對象,則您不擁有該對象,也不應該釋放它(這個規則有少數
的例外,在參考文檔中有顯式的說明)。
8自動釋放池是什麼,如何工作
當您向一個對象發送一個autorelease訊息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。它仍然是個正當的對象,因此自動釋放池定義的範圍內的其它對象可以向它發送訊息。當程式執行到範圍結束的位置時,自動釋放池就會被釋放,池中的所有對象也就被釋放。
1. ojc-c是通過一種"referring counting"(引用計數)的方式來管理記憶體的,對象在開始分配記憶體(alloc)的時候引用計數為一,以後每當碰到有copy,retain的時候引用計數都會加一,每當碰到release和autorelease的時候引用計數就會減一,如果此對象的計數變為了0,就會被系統銷毀.
2. NSAutoreleasePool就是用來做引用計數的管理工作的,這個東西一般不用你管的.
3. autorelease和release沒什麼區別,只是引用計數減一的時機不同而已,autorelease會在對象的使用真正結束的時候才做引用計數減一.
9類Factory 方法是什麼
類Factory 方法的實現是為了向客戶提供方便,它們將分配和初始化合在一個步驟中,返回被建立的對象,並
進行自動釋放處理。這些方法的形式是+ (type)className...(其中className不包括任何首碼)。
Factory 方法可能不僅僅為了方便使用。它們不但可以將分配和初始化合在一起,還可以為初始化過程提供對
象的分配資訊。
類Factory 方法的另一個目的是使類(比如NSWorkspace)提供單件執行個體。雖然init...方法可以確認一
個類在每次程式運行過程只存在一個執行個體,但它需要首先分配一個“生的”執行個體,然後還必須釋放該執行個體。
Factory 方法則可以避免為可能沒有用的對象盲目分配記憶體。
10單件執行個體是什麼
Foundation和Application Kit架構中的一些類只允許建立單件對象,即這些類在當前進程中的唯一執行個體。舉例來說,NSFileManager和NSWorkspace類在使用時都是基於進程進行單件對象的執行個體化。當向這些類請求執行個體的時候,它們會向您傳遞單一執行個體的一個引用,如果該執行個體還不存在,則首先進行執行個體的分配和初始化。單件對象充當控制中心的角色,負責指引或協調類的各種服務。如果類在概念上只有一個執行個體(比如
NSWorkspace),就應該產生一個單件執行個體,而不是多個執行個體;如果將來某一天可能有多個執行個體,您可
以使用單件執行個體機制,而不是Factory 方法或函數。
11動態綁定
—在運行時確定要調用的方法
動態綁定將調用方法的確定也延遲到運行時。在編譯時間,方法的調用並不和代碼綁定在一起,只有在消實發送出來之後,才確定被調用的代碼。通過動態類型和動態綁定技術,您的代碼每次執行都可以得到不同的結果。運行時因子負責確定訊息的接收者和被調用的方法。運行時的訊息分發機製為動態綁定提供支援。當您向一個動態類型確定了的對象發送訊息時,運行環境系統會通過接收者的isa指標定位對象的類,並以此為起點確定被調用的方法,方法和訊息是動態綁定的。而且,您不必在Objective-C代碼中做任何工作,就可以自動擷取動態綁定的好處。您在每次發送訊息時,
特別是當訊息的接收者是動態類型已經確定的對象時,動態綁定就會例行而透明地發生。
12obj-c的優缺點
objc優點:
1) Cateogies
2) Posing
3)動態識別
4)指標計算
5)彈性訊息傳遞
6)不是一個過度複雜的C衍生語言
7) Objective-C與C++可混合編程
缺點:
1)不支援命名空間
2)不支援運算子多載
3)不支援多重繼承
4)使用動態運行時類型,所有的方法都是函數調用,所以很多編譯時間最佳化方法都用不到。(如內嵌函式等),效能低劣。
13sprintf,strcpy,memcpy使用上有什麼要注意的地方
strcpy是一個字串拷貝的函數,它的函數原型為strcpy(char *dst, c*****t char *src);
將src開始的一段字串拷貝到dst開始的記憶體中去,結束的標誌符號為'\0',由於拷貝的長度不是由我們自己控制的,所以這個字串拷貝很容易出錯。具備字串拷貝功能的函數有memcpy,這是一個記憶體拷貝函數,它的函數原型為memcpy(char *dst, c*****t char* src, unsigned int len);
將長度為len的一段記憶體,從src拷貝到dst中去,這個函數的長度可控。但是會有記憶體疊加的問題。
sprintf是格式化函數。將一段資料通過特定的格式,格式化到一個字串緩衝區中去。sprintf格式化的函數的長度不可控,有可能格式化後的字串會超出緩衝區的大小,造成溢出。
14答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functi***** that take an integer argument and return an integer
15.readwrite,readonly,assign,retain,copy,nonatomic屬性的作用
@property是一個屬性訪問聲明,擴號內支援以下幾個屬性:
1,getter=getterName,setter=setterName,設定setter與getter的方法名
2,readwrite,readonly,設定可供存取層級
2,assign,setter方法直接賦值,不進行任何retain操作,為瞭解決原類型與環循引用問題
3,retain,setter方法對參數進行release舊值再retain新值,所有實現都是這個順序(CC上有相關資料)
4,copy,setter方法進行Copy操作,與retain處理流程一樣,先舊值release,再Copy出新的對象,retainCount為1。這是為了減少對內容相關的依賴而引入的機制。
copy是在你不希望a和b共用一塊記憶體時會使用到。a和b各自有自己的記憶體。
5,nonatomic,非原子性訪問,不加同步,多線程並發訪問會提高效能。注意,如果不加此屬性,則預設是兩個存取方法都為原子型事務訪問。鎖被加到所屬對象執行個體級(我是這麼理解的...)。
atomic和nonatomic用來決定編譯器產生的getter和setter是否為原子操作。在多線程環境下,原子操作是必要的,否則有可能引起錯 誤的結果。加了atomic,setter函數會變成下面這樣:
16什麼時候用delegate,什麼時候用Notification?答:delegate針對one-to-one關係,並且reciever可以傳回值給sender,notification可以針對one-to-one/many/none,reciever無法傳回值給sender.所以,delegate用於sender希望接受到reciever的某個功能反饋值,notification用於通知多個object某個事件。
17什麼是KVC和KVO?答:KVC(Key-Value-Coding)內部的實現:一個對象在調用setValue的時候,(1)首先根據方法名找到運行方法的時候所需要的環境參數。(2)他會從自己isa指標結合環境參數,找到具體的方法實現的介面。(3)再直接尋找得來的具體的方法實現。KVO(Key-Value- Observing):當觀察者為一個對象的屬性進行了註冊,被觀察對象的isa指標被修改的時候,isa指標就會指向一個中間類,而不是真實的類。所以isa指標其實不需要指向執行個體對象真實的類。所以我們的程式最好不要依賴於isa指標。在調用類的方法的時候,最好要明確對象執行個體的類名
18ViewController的loadView, viewDidLoad, viewDidUnload分別是在什麼時候調用的?在自訂ViewController的時候這幾個函數裡面應該做什麼工作?答:viewDidLoad在view從nib檔案初始化時調用,loadView在controller的view為nil時調用。此方法在編程實現view時調用,view控制器預設會註冊memory warning notification,當view controller的任何view沒有用的時候,viewDidUnload會被調用,在這裡實現將retain的view release,如果是retain的IBOutlet view屬性則不要在這裡release,IBOutlet會負責release。
19
"NSMutableString *"這個資料類型則是代表"NSMutableString"對象本身,這兩者是有區別的。
而NSString只是對象的指標而已。
面向過程就是分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就可以了。
物件導向是把構成問題事務分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。;
20類別的作用
類別主要有3個作用:
(1)將類的實現分散到多個不同檔案或多個不同架構中。
(2)建立對私人方法的前向引用。
(3)向對象添加非正式協議。
類別的局限性
有兩方面局限性:
(1)無法向類中添加新的執行個體變數,類別沒有位置容納執行個體變數。
(2)名稱衝突,即當類別中的方法與原始類方法名稱衝突時,類別具有更高的優先順序。類別方法將完全取代初始方法從而無法再使用初始方法。
無法添加執行個體變數的局限可以使用字典對象解決
21關鍵字volatile有什麼含意?並給出三個不同的例子:
一個定義為volatile的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,最佳化器在用到
這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在寄存器裡的備份。下面是volatile變數的幾個例子:
?平行裝置的硬體寄存器(如:狀態寄存器)
?一個中斷服務子程式中會訪問到的非自動變數(Non-automatic variables)
?多線程應用中被幾個任務共用的變數
?一個參數既可以是const還可以是volatile嗎?解釋為什麼。
?一個指標可以是volatile嗎?解釋為什麼。
下面是答案:
?是的。一個例子是唯讀狀態寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。
?是的。儘管這並不很常見。一個例子是當一個中服務子程式修該一個指向一個buffer的指標時。
22@synthesize是系統自動產生getter和setter屬性聲明
@dynamic是開發人員自已提供相應的屬性聲明
@dynamic意思是由開發人員提供相應的代碼:對於唯讀屬性需要提供setter,對於讀寫屬性需要提供setter和getter。@synthesize意思是,除非開發人員已經做了,否則由編譯器產生相應的代碼,以滿足屬性聲明。
查閱了一些資料確定@dynamic的意思是告訴編譯器,屬性的擷取與賦值方法由使用者自己實現,不自動產生。
23Difference between shallow copy and deep copy?
淺複製和深複製的區別?
答案:淺層複製:只複製指向對象的指標,而不複製引用對象本身。
深層複製:複製引用對象本身。
意思就是說我有個A對象,複製一份後得到A_copy對象後,對於淺複製來說,A和A_copy指向的是同一個記憶體資源,複製的只不過是是一個指標,對象本身資源
還是只有一份,那如果我們對A_copy執行了修改操作,那麼發現A引用的對象同樣被修改,這其實違背了我們複製拷貝的一個思想。深複製就好理解了,記憶體中存在了
兩份獨立對象本身。
用網上一哥們通俗的話將就是:
淺複製好比你和你的影子,你完蛋,你的影子也完蛋
深複製好比你和你的複製人,你完蛋,你的複製人還活著。
24What is advantage of categories? What is difference between implementing a category and inheritance?
類別的作用?繼承和類別在實現中有何區別?
答案:category可以在不獲悉,不改變原來代碼的情況下往裡面添加新的方法,只能添加,不能刪除修改。
並且如果類別和原來類中的方法產生名稱衝突,則類別將覆蓋原來的方法,因為類別具有更高的優先順序。
類別主要有3個作用:
(1)將類的實現分散到多個不同檔案或多個不同架構中。
(2)建立對私人方法的前向引用。
(3)向對象添加非正式協議。
繼承可以增加,修改或者刪除方法,並且可以增加屬性。
25.Difference between categories and extensions?
類別和類擴充的區別。
答案:category和extensions的不同在於後者可以添加屬性。另外後者添加的方法是必須要實現的。
extensions可以認為是一個私人的Category。
26.Difference between protocol in objective c and interfaces in java?
oc中的協議和java中的介面概念有何不同?
答案:OC中的代理有2層含義,官方定義為formal和informal protocol。前者和Java介面一樣。
informal protocol中的方法屬於設計模式考慮範疇,不是必須實現的,但是如果有實現,就會改變類的屬性。
其實關於正式協議,類別和非正式協議我很早前學習的時候大致看過,也寫在了學習教程裡
“非正式協議概念其實就是類別的另一種表達方式“這裡有一些你可能希望實現的方法,你可以使用他們更好的完成工作”。
這個意思是,這些是可選的。比如我門要一個更好的方法,我們就會申明一個這樣的類別去實現。然後你在後期可以直接使用這些更好的方法。
這麼看,總覺得類別這玩意兒有點像協議的可選協議。"
現在來看,其實protocal已經開始對兩者都統一和規範起來操作,因為資料中說“非正式協議使用interface修飾“,
現在我們看到協議中兩個修飾詞:“必須實現(@requied)”和“可選實現(@optional)”。
26What are KVO and KVC?
答案:kvc:鍵-值編碼是一種間接訪問對象的屬性使用字串來識別屬性,而不是通過調用存取方法,直接或通過執行個體變數訪問的機制。
很多情況下可以簡化程式碼。apple文檔其實給了一個很好的例子。
kvo:索引值觀察機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼。
具體用看到嗯哼用到過的一個地方是對於按鈕點擊變化狀態的的監控。
比如我自訂的一個button
[cpp]
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"highlighted"] ) {
[self setNeedsDisplay];
}
}
對於系統是根據keypath去取的到相應的值發生改變,理論上來說是和kvc機制的道理是一樣的。
對於kvc機制如何通過key尋找到value:
“當通過KVC調用對象時,比如:[self valueForKey:@”someKey”]時,程式會自動試圖通過幾種不同的方式解析這個調用。首先尋找對象是否帶有someKey這個方法,如果沒找到,會繼續尋找對象是否帶有someKey這個執行個體變數(iVar),如果還沒有找到,程式會繼續試圖調用-(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實現的話,程式會拋出一個NSUndefinedKeyException異常錯誤。
(cocoachina.com註:Key-Value Coding尋找方法的時候,不僅僅會尋找someKey這個方法,還會尋找getsomeKey這個方法,前面加一個get,或者_someKey以及_getsomeKey這幾種形式。同時,尋找執行個體變數的時候也會不僅僅尋找someKey這個變數,也會尋找_someKey這個變數是否存在。)
設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發生前,有最後的機會響應這個請求。這樣做有很多好處,下面的兩個例子說明了這樣做的好處。“
來至cocoa,這個說法應該挺有道理。
因為我們知道button卻是存在一個highlighted執行個體變數.因此為何上面我們只是add一個相關的keypath就行了,
27What is purpose of delegates?
代理的作用?
答案:代理的目的是改變或傳遞控制鏈。允許一個類在某些特定時刻通知到其他類,而不需要擷取到那些類的指標。可以減少架構複雜度。
另外一點,代理可以理解為java中的回調監聽機制的一種類似。
28What are mutable and immutable types in Objective C?
oc中可修改和不可以修改類型。
答案:可修改不可修改的集合類。這個我個人簡單理解就是可動態添加修改和不可動態添加修改一樣。
比如NSArray和NSMutableArray。前者在初始化後的記憶體控制項就是固定不可變的,後者可以添加等,可以動態申請新的記憶體空間
29When we call objective c is runtime language what does it mean?
我們說的oc是動態運行時語言是什麼意思?
答案:多態。主要是將資料類型的確定由編譯時間,延遲到了運行時。
這個問題其實淺涉及到兩個概念,運行時和多態。
簡單來說,運行時機制使我們直到運行時才去決定一個對象的類別,以及調用該類別對象指定方法。
多態:不同對象以自己的方式響應相同的訊息的能力叫做多態。意思就是假設生物類(life)都用有一個相同的方法-eat;
那人類屬於生物,豬也屬於生物,都繼承了life後,實現各自的eat,但是調用是我們只需調用各自的eat方法。
也就是不同的對象以自己的方式響應了相同的訊息(響應了eat這個選取器)。
因此也可以說,運行時機制是多態的基礎?~~~
30what is difference between NSNotification and protocol?
通知和協議的不同之處?
答案:協議有控制鏈(has-a)的關係,通知沒有。
首先我一開始也不太明白,什麼叫控制鏈(專業術語了~)。但是簡單分析下通知和代理的行為模式,我們大致可以有自己的理解
簡單來說,通知的話,它可以一對多,一條訊息可以發送給多個訊息接受者。
代理按我們的理解,到不是直接說不能一對多,比如我們知道的明星經濟代理人,很多時候一個經濟人負責好幾個明星的事務。
只是對於不同明星間,代理的事物對象都是不一樣的,一一對應,不可能說明天要處理A明星要一個發布會,代理人發出處理髮布會的訊息後,別稱B的
發布會了。但是通知就不一樣,他只關心發出通知,而不關心多少接收到感興趣要處理。
因此控制鏈(has-a從英語單詞大致可以看出,單一擁有和可控制的對應關係。