一、(一共三十題)
1.main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
答案:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],執(zhí)行結(jié)果是2,5。a+1不是首地址+1,系統(tǒng)會(huì)認(rèn)為加一個(gè)a數(shù)組的偏移,是偏移了一個(gè)數(shù)組的大小(本例是5個(gè)int)
int *ptr=(int *)(&a+1);
則ptr實(shí)際是&(a[5]),也就是a+5
原因如下:a是數(shù)組指針,其類(lèi)型為int (*)[5];而指針加1要根據(jù)指針類(lèi)型加上一定的值,不同類(lèi)型的指針+1之后增加的大小不同。a是長(zhǎng)度為5的int數(shù)組指針,所以要加5*sizeof(int),以ptr實(shí)際是a[5]。但是prt與(&a+1)類(lèi)型是不一樣的(這點(diǎn)很重要)。所以prt-1只會(huì)減去sizeof(int*),a,&a的地址是一樣的,但意思不一樣。a是數(shù)組首地址,也就是a[0]的地址,&a是對(duì)象(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a[1],&a+1是下一個(gè)對(duì)象的地址,即a[5].
2.以下為Windows NT下的32位C++程序,請(qǐng)計(jì)算sizeof的值
void Func ( char str[100])
{sizeof( str ) = ?}
void *p = malloc( 100 );
sizeof ( p ) = ?
答案:sizeof( str )、sizeof ( p )都為4。
3.還是考指針,不過(guò)我對(duì)cocoa的代碼還是不太熟悉大概是這樣的- NSString *getNSString(void)
{
NSString *output=@"Thisis a main test\n";
return output;
}
-main(void)
{NSString *a=@"Main";
NSString *aString = [NSStringstringWithString:@"%@",getNSString(a)];NSLog(@"%@\n", aString);
}
答案:最后問(wèn)輸出的字符串:NULL,output在函數(shù)返回后,內(nèi)存已經(jīng)被釋放。
4.用預(yù)處理指令#define聲明一個(gè)常數(shù),用以表明1年中有多少秒(忽略閏年問(wèn)題)寫(xiě)一個(gè)"標(biāo)準(zhǔn)"宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。
答案:#defineSECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
5.寫(xiě)一個(gè)委托的interface
答案:@protocol MyDelegate;
@interface MyClass: NSObject
{
id delegate;
}
//委托方法
@protocol?MyDelegate
- (void)didJobs:(NSArray*)args;
@end
6.寫(xiě)一個(gè)NSString類(lèi)的實(shí)現(xiàn)-(id)initWithCString:(const char *)nullTerminatedCStringencoding:(NSStringEncoding)encoding; -(void)dealloc;
答案:+ (id) stringWithCString:(const char*)nullTerminatedCString
encoding: (NSStringEncoding)encoding
{
NSString*obj;
obj = [self allocWithZone:NSDefaultMallocZone()];
obj = [obj initWithCString:nullTerminatedCString encoding: encoding];
return AUTORELEASE(obj);
}
7.obj-c有多重繼承么?不是的話有什么替代方法?
答案:cocoa中所有的類(lèi)都是NSObject的子類(lèi),多繼承在這里是用protocol委托代理來(lái)實(shí)現(xiàn)的,你不用去考慮繁瑣的多繼承,虛基類(lèi)的概念.ood的多態(tài)特性在obj-c中通過(guò)委托來(lái)實(shí)現(xiàn).
8.obj-c有私有方法么?私有變量呢
答案:objective-c -類(lèi)里面的方法只有兩種,靜態(tài)方法和實(shí)例方法
在Objective‐C中,所有實(shí)例變量默認(rèn)都是受保護(hù)的,所有實(shí)例方法默認(rèn)都是公有的
9.關(guān)鍵字const有什么含意?關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子。static關(guān)鍵字的作用,extern "C"的作用
答案:const意味著"只讀",聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。
關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。如果
你曾花很多時(shí)間清理其它人留下的垃圾,你就會(huì)很快學(xué)會(huì)感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會(huì)留下的垃圾讓別人來(lái)清
理的。)
通過(guò)給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。
合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無(wú)意的代碼修改。簡(jiǎn)而言之,這樣可以減少bug的出現(xiàn)。
(1)欲阻止一個(gè)變量被改變,可以使用const關(guān)鍵字。在定義該const變量時(shí),通常需要對(duì)它進(jìn)行初
始化,因?yàn)橐院缶蜎](méi)有機(jī)會(huì)再去改變它了;
(2)對(duì)指針來(lái)說(shuō),可以指定指針本身為const,也可以指定指針?biāo)傅臄?shù)據(jù)為const,或二者同時(shí)指
定為const;
(3)在一個(gè)函數(shù)聲明中,const可以修飾形參,表明它是一個(gè)輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值;
(4)對(duì)于類(lèi)的成員函數(shù),若指定其為const類(lèi)型,則表明其是一個(gè)常函數(shù),不能修改類(lèi)的成員變量;
(5)對(duì)于類(lèi)的成員函數(shù),有時(shí)候必須指定其返回值為const類(lèi)型,以使得其返回值不為“左值”。
static關(guān)鍵字的作用:
(1)函數(shù)體內(nèi)static變量的作用范圍為該函數(shù)體,不同于auto變量,該變量的內(nèi)存只被分配一次,
因此其值在下次調(diào)用時(shí)仍維持上次的值;
(2)在模塊內(nèi)的static全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn);
(3)在模塊內(nèi)的static函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明
它的模塊內(nèi);
(4)在類(lèi)中的static成員變量屬于整個(gè)類(lèi)所擁有,對(duì)類(lèi)的所有對(duì)象只有一份拷貝;
(5)在類(lèi)中的static成員函數(shù)屬于整個(gè)類(lèi)所擁有,這個(gè)函數(shù)不接收this指針,因而只能訪問(wèn)類(lèi)的static成員變量。
extern "C"的作用
(1)被extern
"C"限定的函數(shù)或變量是extern類(lèi)型的;
extern是C/C++語(yǔ)言中表明函數(shù)和全局變量作用范圍(可見(jiàn)性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器,
其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。
(2)被extern
"C"修飾的變量和函數(shù)是按照C語(yǔ)言方式編譯和連接的;
extern "C"的慣用法
(1)在C++中引用C語(yǔ)言中的函數(shù)和變量,在包含C語(yǔ)言頭文件(假設(shè)為cExample.h)時(shí),需進(jìn)行下列處理:
extern "C"
{#include "cExample.h"}
而在C語(yǔ)言的頭文件中,對(duì)其外部函數(shù)只能指定為extern類(lèi)型,C語(yǔ)言中不支持extern "C"聲明,在.c文件中包含了extern "C"時(shí)會(huì)出現(xiàn)編譯語(yǔ)法錯(cuò)誤。
(2)在C中引用C++語(yǔ)言中的函數(shù)和變量時(shí),C++的頭文件需添加extern "C",但是在C語(yǔ)言中不
能直接引用聲明了extern "C"的該頭文件,應(yīng)該僅將C文件中將C++中定義的extern "C"函數(shù)聲明為extern類(lèi)型。
10.為什么標(biāo)準(zhǔn)頭文件都有類(lèi)似以下的結(jié)構(gòu)?#ifndef __INCvxWorksh#define __INCvxWorksh#ifdef __cplusplusextern "C" {#endif/*...*/#ifdef __cplusplus}#endif#endif /*__INCvxWorksh */
答案:顯然,頭文件中的編譯宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif”的作用是防止該頭文件被重復(fù)引用。
11.#import跟#include的區(qū)別,@class呢?
答案:@class一般用于頭文件中需要聲明該類(lèi)的某個(gè)實(shí)例變量的時(shí)候用到,在m文件中還是需要使用#import而#import比起#include的好處就是不會(huì)引起交叉編譯
12.MVC模式的理解
答案:MVC設(shè)計(jì)模式考慮三種對(duì)象:模型對(duì)象、視圖對(duì)象、和控制器對(duì)象。模型對(duì)象代表特別的知識(shí)和專(zhuān)業(yè)技能,它們負(fù)責(zé)保有應(yīng)用程序的數(shù)據(jù)和定義操作數(shù)據(jù)的邏輯。視圖對(duì)象知道如何顯示應(yīng)用程序的模型數(shù)據(jù),而且可能允許用戶對(duì)其進(jìn)行編輯。控制器對(duì)象是應(yīng)用程序的視圖對(duì)象和模型對(duì)象之間的協(xié)調(diào)者。
13.線程與進(jìn)程的區(qū)別和聯(lián)系?線程是否具有相同的堆棧? dll是否有獨(dú)立的堆棧?
答案:進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性。
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒(méi)有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。
14.列舉幾種進(jìn)程的同步機(jī)制,并比較其優(yōu)缺點(diǎn)。進(jìn)程之間通信的途徑進(jìn)程死鎖的原因死鎖的4個(gè)必要條件死鎖的處理
答案:同步機(jī)制:原子操作,信號(hào)量機(jī)制,自旋鎖,管程,會(huì)合,分布式系統(tǒng)
進(jìn)程之間通信的途徑:共享存儲(chǔ)系統(tǒng)消息傳遞系統(tǒng)管道:以文件系統(tǒng)為基礎(chǔ)
進(jìn)程死鎖的原因:資源競(jìng)爭(zhēng)及進(jìn)程推進(jìn)順序非法
死鎖的4個(gè)必要條件:互斥、請(qǐng)求保持、不可剝奪、環(huán)路
死鎖的處理:鴕鳥(niǎo)策略、預(yù)防策略、避免策略、檢測(cè)與解除死鎖
15.堆和棧的區(qū)別
答案:管理方式:對(duì)于棧來(lái)講,是由編譯器自動(dòng)管理,無(wú)需我們手工控制;對(duì)于堆來(lái)說(shuō),釋放工作由程序員控制,容易產(chǎn)生memory leak。
申請(qǐng)大小:棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在WINDOWS下,棧的大小是2M(也有的說(shuō)是1M,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過(guò)棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來(lái)存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見(jiàn),堆獲得的空間比較靈活,也比較大。
碎片問(wèn)題:對(duì)于堆來(lái)講,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對(duì)于棧來(lái)講,則不會(huì)存在這個(gè)問(wèn)題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對(duì)應(yīng),以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出
分配方式:堆都是動(dòng)態(tài)分配的,沒(méi)有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無(wú)需我們手工實(shí)現(xiàn)。
分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專(zhuān)門(mén)的寄存器存放棧的地址,壓棧出棧都有專(zhuān)門(mén)的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫(kù)提供的,它的機(jī)制是很復(fù)雜的。
16.什么是鍵-值,鍵路徑是什么
答案:模型的性質(zhì)是通過(guò)一個(gè)簡(jiǎn)單的鍵(通常是個(gè)字符串)來(lái)指定的。視圖和控制器通過(guò)鍵來(lái)查找相應(yīng)的屬性值。在一個(gè)給定的實(shí)體中,同一個(gè)屬性的所有值具有相同的數(shù)據(jù)類(lèi)型。鍵-值編碼技術(shù)用于進(jìn)行這樣的查找—它是一種間接訪問(wèn)對(duì)象屬性的機(jī)制。
鍵路徑是一個(gè)由用點(diǎn)作分隔符的鍵組成的字符串,用于指定一個(gè)連接在一起的對(duì)象性質(zhì)序列。第一個(gè)鍵的性質(zhì)是由先前的性質(zhì)決定的,接下來(lái)每個(gè)鍵的值也是相對(duì)于其前面的性質(zhì)。鍵路徑使您可以以獨(dú)立于模型實(shí)現(xiàn)的方式指定相關(guān)對(duì)象的性質(zhì)。通過(guò)鍵路徑,您可以指定對(duì)象圖中的一個(gè)任意深度的路徑,使其指向相關(guān)對(duì)象的特定屬性。
17.c和obj-c如何混用
答案:1)obj-c的編譯器處理后綴為m的文件時(shí),可以識(shí)別obj-c和c的代碼,處理mm文件可以識(shí)別obj-c,c,c++代碼,但cpp文件必須只能用c/c++代碼,而且cpp文件include的頭文件中,也不能出現(xiàn)obj- c的代碼,因?yàn)閏pp只是cpp。
2)在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是問(wèn)題
3)在cpp中混用obj- c其實(shí)就是使用obj-c編寫(xiě)的模塊是我們想要的。
如果模塊以類(lèi)實(shí)現(xiàn),那么要按照cpp class的標(biāo)準(zhǔn)寫(xiě)類(lèi)的定義,頭文件中不能出現(xiàn)obj-c的東西,包括#import cocoa的。實(shí)現(xiàn)文件中,即類(lèi)的實(shí)現(xiàn)代碼中可以使用obj-c的東西,可以import,只是后綴是mm。如果模塊以函數(shù)實(shí)現(xiàn),那么頭文件要按c的格式聲明函數(shù),實(shí)現(xiàn)文件中,c++函數(shù)內(nèi)部可以用obj-c,但后綴還是mm或m。
總結(jié):只要cpp文件和cpp include的文件中不包含obj-c的東西就可以用了,cpp混用obj-c的關(guān)鍵是使用接口,而不能直接使用實(shí)現(xiàn)代碼,實(shí)際上cpp混用的是obj-c編譯后的o文件,這個(gè)東西其實(shí)是無(wú)差別的,所以可以用。obj-c的編譯器支持cpp.
18.目標(biāo)-動(dòng)作機(jī)制
答案:目標(biāo)是動(dòng)作消息的接收者。一個(gè)控件,或者更為常見(jiàn)的是它的單元,以插座變量(參見(jiàn)"插座變量"部分)的形式保有其動(dòng)作消息的目標(biāo)。
動(dòng)作是控件發(fā)送給目標(biāo)的消息,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動(dòng)作而實(shí)現(xiàn)的方法。程序需要某些機(jī)制來(lái)進(jìn)行事件和指令的翻譯。這個(gè)機(jī)制就是目標(biāo)-動(dòng)作機(jī)制。
19.cocoa touch框架
答案:iPhone OS應(yīng)用程序的基礎(chǔ)Cocoa Touch框架重用了許多Mac系統(tǒng)的成熟模式,但是它更多地專(zhuān)注于觸摸的接口和優(yōu)化。UIKit為您提供了在iPhone OS上實(shí)現(xiàn)圖形,事件驅(qū)動(dòng)程序的基本工具,其建立在和Mac OS X中一樣的Foundation框架上,包括文件處理,網(wǎng)絡(luò),字符串操作等。
Cocoa Touch具有和iPhone用戶接口一致的特殊設(shè)計(jì)。有了UIKit,您可以使用iPhone OS上的獨(dú)特的圖形接口控件,按鈕,以及全屏視圖的功能,您還可以使用加速儀和多點(diǎn)觸摸手勢(shì)來(lái)控制您的應(yīng)用。
各色俱全的框架除了UIKit外,Cocoa Touch包含了創(chuàng)建世界一流iPhone應(yīng)用程序需要的所有框架,從三維圖形,到專(zhuān)業(yè)音效,甚至提供設(shè)備訪問(wèn)API以控制攝像頭,或通過(guò)GPS獲知當(dāng)前位置。Cocoa Touch既包含只需要幾行代碼就可以完成全部任務(wù)的強(qiáng)大的Objective-C框架,也在需要時(shí)提供基礎(chǔ)的C語(yǔ)言API來(lái)直接訪問(wèn)系統(tǒng)。這些框架包括:
Core Animation:通過(guò)Core Animation,您就可以通過(guò)一個(gè)基于組合獨(dú)立圖層的簡(jiǎn)單的編程模型來(lái)創(chuàng)建豐富的用戶體驗(yàn)。
Core Audio:Core Audio是播放,處理和錄制音頻的專(zhuān)業(yè)技術(shù),能夠輕松為您的應(yīng)用程序添加強(qiáng)大的音頻功能。
Core Data:提供了一個(gè)面向?qū)ο蟮臄?shù)據(jù)管理解決方案,它易于使用和理解,甚至可處理任何應(yīng)用或大或小的數(shù)據(jù)模型。
下面是Cocoa Touch中一小部分可用的框架:
音頻和視頻:Core Audio、OpenAL、Media Library、AV Foundation
數(shù)據(jù)管理:Core Data、SQLite
圖形和動(dòng)畫(huà):Core Animation、OpenGL ES、Quartz 2D
網(wǎng)絡(luò)/li>:onjour、WebKit、BSD Sockets
用戶應(yīng)用:Address Book、Core Location、ap Kit、tore Kit
20.objc的內(nèi)存管理
答案:1、如果您通過(guò)分配和初始化(比如[[MyClass alloc]
init])的方式來(lái)創(chuàng)建對(duì)象,您就擁有這個(gè)對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。這個(gè)規(guī)則在使用NSObject的便利方法new時(shí)也同樣適用。
2、如果您拷貝一個(gè)對(duì)象,您也擁有拷貝得到的對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。
3、如果您保持一個(gè)對(duì)象,您就部分擁有這個(gè)對(duì)象,需要在不再使用時(shí)釋放該對(duì)象。反過(guò)來(lái),如果您從其它對(duì)象那里接收到一個(gè)對(duì)象,則您不擁有該對(duì)象,也不應(yīng)該釋放它(這個(gè)規(guī)則有少數(shù)的例外,在參考文檔中有顯式的說(shuō)明)。
21.自動(dòng)釋放池是什么,如何工作
答案:當(dāng)您向一個(gè)對(duì)象發(fā)送一個(gè)autorelease消息時(shí),Cocoa就會(huì)將該對(duì)象的一個(gè)引用放入到最新的自動(dòng)釋放池。它仍然是個(gè)正當(dāng)?shù)膶?duì)象,因此自動(dòng)釋放池定義的作用域內(nèi)的其它對(duì)象可以向它發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動(dòng)釋放池就會(huì)被釋放,池中的所有對(duì)象也就被釋放。
1.ojc-c是通過(guò)一種"referring counting"(引用計(jì)數(shù))的方式來(lái)管理內(nèi)存的,對(duì)象在開(kāi)始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為一,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加一,每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減一,如果此對(duì)象的計(jì)數(shù)變?yōu)榱?,系統(tǒng)才會(huì)調(diào)用dealloc真正銷(xiāo)毀這個(gè)對(duì)象.
2. NSAutoreleasePool就是用來(lái)做引用計(jì)數(shù)的管理工作的,這個(gè)東西一般不用你管的.
3. autorelease和release沒(méi)什么區(qū)別,只是引用計(jì)數(shù)減一的時(shí)機(jī)不同而已,autorelease會(huì)在對(duì)象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減一.
22.類(lèi)工廠方法是什么(就是便利構(gòu)造器)
答案:類(lèi)工廠方法的實(shí)現(xiàn)是為了向客戶提供方便,它們將分配和初始化合在一個(gè)步驟中,返回被創(chuàng)建的對(duì)象,并進(jìn)行自動(dòng)釋放處理。這些方法的形式是+ (type)className...(其中className不包括任何前綴)。
工廠方法可能不僅僅為了方便使用。它們不但可以將分配和初始化合在一起,還可以為初始化過(guò)程提供對(duì)象的分配信息。
類(lèi)工廠方法的另一個(gè)目的是使類(lèi)(比如NSWorkspace)提供單件實(shí)例。雖然init...方法可以確認(rèn)一個(gè)類(lèi)在每次程序運(yùn)行過(guò)程只存在一個(gè)實(shí)例,但它需要首先分配一個(gè)“生的”實(shí)例,然后還必須釋放該實(shí)例。
工廠方法則可以避免為可能沒(méi)有用的對(duì)象盲目分配內(nèi)存。
23.單件實(shí)例是什么
答案:Foundation和Application Kit框架中的一些類(lèi)只允許創(chuàng)建單件對(duì)象,即這些類(lèi)在當(dāng)前進(jìn)程中的唯一實(shí)例。舉例來(lái)說(shuō),NSFileManager和NSWorkspace類(lèi)在使用時(shí)都是基于進(jìn)程進(jìn)行單件對(duì)象的實(shí)例化。當(dāng)向這些類(lèi)請(qǐng)求實(shí)例的時(shí)候,它們會(huì)向您傳遞單一實(shí)例的一個(gè)引用,如果該實(shí)例還不存在,則首先進(jìn)行實(shí)例的分配和初始化。單件對(duì)象充當(dāng)控制中心的角色,負(fù)責(zé)指引或協(xié)調(diào)類(lèi)的各種服務(wù)。如果類(lèi)在概念上只有一個(gè)實(shí)例(比如NSWorkspace),就應(yīng)該產(chǎn)生一個(gè)單件實(shí)例,而不是多個(gè)實(shí)例;如果將來(lái)某一天可能有多個(gè)實(shí)例,您可以使用單件實(shí)例機(jī)制,而不是工廠方法或函數(shù)。
24.動(dòng)態(tài)綁定
答案:動(dòng)態(tài)綁定——在運(yùn)行時(shí)確定要調(diào)用的方法。動(dòng)態(tài)綁定將調(diào)用方法的確定也推遲到運(yùn)行時(shí)。在編譯時(shí),方法的調(diào)用并不和代碼綁定在一起,只有在消實(shí)發(fā)送出來(lái)之后,才確定被調(diào)用的代碼。通過(guò)動(dòng)態(tài)類(lèi)型和動(dòng)態(tài)綁定技術(shù),您的代碼每次執(zhí)行都可以得到不同的結(jié)果。運(yùn)行時(shí)因子負(fù)責(zé)確定消息的接收者和被調(diào)用的方法。運(yùn)行時(shí)的消息分發(fā)機(jī)制為動(dòng)態(tài)綁定提供支持。當(dāng)您向一個(gè)動(dòng)態(tài)類(lèi)型確定了的對(duì)象發(fā)送消息時(shí),運(yùn)行環(huán)境系統(tǒng)會(huì)通過(guò)接收者的isa指針定位對(duì)象的類(lèi),并以此為起點(diǎn)確定被調(diào)用的方法,方法和消息是動(dòng)態(tài)綁定的。而且,您不必在Objective-C代碼中做任何工作,就可以自動(dòng)獲取動(dòng)態(tài)綁定的好處。您在每次發(fā)送消息時(shí),特別是當(dāng)消息的接收者是動(dòng)態(tài)類(lèi)型已經(jīng)確定的對(duì)象時(shí),動(dòng)態(tài)綁定就會(huì)例行而透明地發(fā)生。
25.obj-c的優(yōu)缺點(diǎn)
答案:objc優(yōu)點(diǎn):1) Cateogies 2) Posing()3)動(dòng)態(tài)識(shí)別4)指標(biāo)計(jì)算5)彈性訊息傳遞6)不是一個(gè)過(guò)度復(fù)雜的C衍生語(yǔ)言7) Objective-C與C++可混合編程
缺點(diǎn): 1)不支援命名空間2)不支持運(yùn)算符重載3)不支持多重繼承4)使用動(dòng)態(tài)運(yùn)行時(shí)類(lèi)型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時(shí)優(yōu)化方法都用不到。(如內(nèi)聯(lián)函等),性能低劣。
26.sprintf,strcpy,memcpy使用上有什么要注意的地方
答案:strcpy是一個(gè)字符串拷貝的函數(shù),它的函數(shù)原型為strcpy(char *dst,
const char *src);將src開(kāi)始的一段字符串拷貝到dst開(kāi)始的內(nèi)存中去,結(jié)束的標(biāo)志符號(hào)為'\0',由于拷貝的長(zhǎng)度不是由我們自己控制的,所以這個(gè)字符串拷貝很容易出錯(cuò)。
具備字符串拷貝功能的函數(shù)有memcpy,這是一個(gè)內(nèi)存拷貝函數(shù),它的函數(shù)原型為memcpy(char *dst, const
char* src, unsigned int len);將長(zhǎng)度為len的一段內(nèi)存,從src拷貝到dst中去,這個(gè)函數(shù)的長(zhǎng)度可控。但是會(huì)有內(nèi)存疊加的問(wèn)題。
sprintf是格式化函數(shù)。將一段數(shù)據(jù)通過(guò)特定的格式,格式化到一個(gè)字符串緩沖區(qū)中去。sprintf格式化的函數(shù)的長(zhǎng)度不可控,有可能格式化后的字符串會(huì)超出緩沖區(qū)的大小,造成溢出。
27.用變量a給出下面的定義
a)一個(gè)整型數(shù)(An integer)
b)一個(gè)指向整型數(shù)的指針(A pointer to an integer)
c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(A pointer to a
pointer to an intege)r
d)一個(gè)有10個(gè)整型數(shù)的數(shù)組(An array of 10 integers)
e)一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的。(An array of 10
pointers to integers)
f)一個(gè)指向有10個(gè)整型數(shù)數(shù)組的指針(A pointer to an array of 10
integers)
g)一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(A pointer to afunction that takes an integer as an argumentand returns an integer)
h)一個(gè)有10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(An array of ten
pointers to functions t hat take an integer argument and return an integer)
答案:
a) int a; // An integer
b) int *a; // A pointer toan integer
c) int **a; // A pointer toa pointer to an integer
d) int a[10]; // An array of10 integers
e) int *a[10]; // An arrayof 10 pointers to integers
f) int (*a)[10]; // Apointer to an array of 10 integers
g) int (*a)(int); // A pointerto a function a thattakes an integerargument and returns an integer
h) int (*a[10])(int); // Anarray of 10 pointers to functionsthattake an integer argument and return an integer
28.cocoa有哪些設(shè)計(jì)模式?
答案:
29.socket編程中如何判斷異步connect是否成功
答案:創(chuàng)建一個(gè)socket,設(shè)為異步socket(fcntl),將socket加入epoll,connect到遠(yuǎn)端(此時(shí)connect調(diào)用返回非0,但errno為EINPROGRESS,表示正在建立連接中)
epoll_wait之捕獲到EPOLLOUT事件,此時(shí)便認(rèn)為connect已經(jīng)成功,client端開(kāi)始發(fā)消息
這個(gè)過(guò)程通常能夠運(yùn)轉(zhuǎn),但是線上環(huán)境復(fù)雜多變,如果發(fā)生這種情況:server進(jìn)程調(diào)用listen開(kāi)始偵聽(tīng)后,被gdb或信號(hào)掛住了,此時(shí)異步connect會(huì)怎樣?很遺憾,client端的epoll_wait依然返回EPOLLOUT,甚至往此socket里發(fā)消息都返回成功,只有當(dāng)發(fā)的消息多得占完了server端的tcp緩沖以后(窗口收縮到很小),send調(diào)用才開(kāi)始失敗。這時(shí)候用losf -i看網(wǎng)絡(luò)連接也很有趣,client端的機(jī)器顯示連接建立了,server端的卻顯示沒(méi)有這個(gè)連接。
仔細(xì)想想,OS這樣做是正確的,畢竟connect的語(yǔ)義只是“連接”,當(dāng)server掛住時(shí),連接還是能成功的,但你能不能往里面發(fā)消息那就是另外一回事了。
所以對(duì)于應(yīng)用來(lái)說(shuō),異步socket想要知道connect后連接是不是可以正常收發(fā)數(shù)據(jù)了,還是要靠應(yīng)用層的一問(wèn)一答才能知道。
30.[[[nil
retain]retain]release]有什么問(wèn)題
答案:沒(méi)有問(wèn)題
31.cocoa架構(gòu)
答案:
32.readwrite,readonly,assign,retain,copy,nonatomic屬性的作用
答案:@property是 一個(gè)屬性訪問(wèn)聲明,擴(kuò)號(hào)內(nèi)支持以下幾個(gè)屬性:
1.getter=getterName,setter=setterName,設(shè)置setter與getter的方法名
2.readwrite,readonly,設(shè)置可供訪問(wèn)級(jí)別
3.assign,setter方法直接賦值,不進(jìn)行 任何retain操作,為了解決原類(lèi)型與環(huán)循引用問(wèn)題
4.retain,setter方法對(duì)參數(shù)進(jìn)行release舊值再retain新值,所有 實(shí)現(xiàn)都是這個(gè)順序(CC上有相關(guān)資料)
5.copy,setter方法進(jìn)行Copy操作,與retain處理流程一樣,先舊值release,再Copy出新的對(duì)象,retainCount為1。這是為了減少對(duì)上下文的依賴而引入的機(jī)制。
6.nonatomic,非原子性訪問(wèn),不加同步,多線程并發(fā)訪問(wèn)會(huì)提高性能。注意,如果不加此屬性,則默認(rèn)是兩個(gè)訪問(wèn)方法都為原子型事務(wù)訪問(wèn)。鎖被加到所屬對(duì)象實(shí)例級(jí)(我是這么理解的...)。
二、(一共九題)
1.絡(luò)編程中設(shè)計(jì)并發(fā)服務(wù)器,使用多進(jìn)程與多線程,請(qǐng)問(wèn)有什么區(qū)別?
a)答1)進(jìn)程:子進(jìn)程是父進(jìn)程的復(fù)制品。子進(jìn)程獲得父進(jìn)程數(shù)據(jù)空間、堆和棧的復(fù)制品。2)線程:相對(duì)與進(jìn)程而言,線程是一個(gè)更加接近與執(zhí)行體的概念,它可以與同進(jìn)程的其他線程共享數(shù)據(jù),但擁有自己的棧空間,擁有獨(dú)立的執(zhí)行序列。
線程和進(jìn)程在使用上各有優(yōu)缺點(diǎn):線程執(zhí)行開(kāi)銷(xiāo)小,但不利于資源管理和保護(hù);而進(jìn)程正相反。同時(shí),線程適合于在SMP機(jī)器上運(yùn)行,而進(jìn)程則可以跨機(jī)器遷移。
2.數(shù)組a[N],存放了1至N-1個(gè)數(shù),其中某個(gè)數(shù)重復(fù)一次。寫(xiě)一個(gè)函數(shù),找出被重復(fù)的數(shù)字.時(shí)間復(fù)雜度必須為o(N)函數(shù)原型:int do_dup(int a[],int N)
答:int do_dup(int a[],intN)
{
int sum= 0;
int sum2;
for(int i=0;i
{
Sum+=a[i];
}
Sum2 = (1+N-1)*N/2;
Return (sum-sum2);
}
3.一語(yǔ)句實(shí)現(xiàn)x是否為2的若干次冪的判斷
答:
方法1)int i = 512;
cout <<
boolalpha<< ((i & (i - 1)) ?false : true) << endl;//位與為0,則表示是2的若干次冪
方法2)return (x>>N==1);
4.unsigned int
intvert(unsigned int x,int p,intn)實(shí)現(xiàn)對(duì)x的進(jìn)行轉(zhuǎn)換,p為起始轉(zhuǎn)化位,n為需要轉(zhuǎn)換的長(zhǎng)度,假設(shè)起始點(diǎn)在右邊.如x=0b00010001,p=4,n=3轉(zhuǎn)換后x=0b0110 0001
答:unsigned int intvert(unsigned int x,int p,int n)//假定p=4,n=3
unsigned int _t = 0;unsignedint _a = 1;
for(int i = 0; i
++i)//循環(huán)的目的主要是-t_t |=_a;
_a = _a<<1;
_t =_t<
x ^=_t;
return x;
5.什么是預(yù)編譯,何時(shí)需要預(yù)編譯?
答:預(yù)編譯又稱(chēng)為預(yù)處理,是做些代碼文本的替換工作。處理#開(kāi)頭的指令,比如拷貝#include包含的文件代碼,#define宏定義的替換,條件編譯等,就是為編譯做的預(yù)備工作的階段,主要處理#開(kāi)始的預(yù)編譯指令,預(yù)編譯指令指示了在程序正式編譯前就由編譯器進(jìn)行的操作,可以放在程序中的任何位置。c編譯系統(tǒng)在對(duì)程序進(jìn)行通常的編譯之前,先進(jìn)行預(yù)處理。c提供的預(yù)處理功能主要有以下三種:1)宏定義2)文件包含3)條件編譯。
6.下述三個(gè)有什么區(qū)別?
char * const p;
char const * p
const char *p
char * const p; //常量指針,p的值不可以修改
char const * p;//指向常量的指針,指向的常量值不可以改
const char *p;//和char const *p
7.解釋下列輸出結(jié)果
char str1[] ="abc";char str2[] = "abc";const char str3[] ="abc";
const char str4[] ="abc";const char *str5 = "abc";
const char *str6 ="abc";char *str7 = "abc";char *str8 = "abc";
cout << (str1 == str2 )<< endl;cout << ( str3 == str4 )<< endl;
cout << ( str5 == str6)<< endl;cout << ( str7 == str8 )<< endl;
結(jié)果是:0 0 1 1
解答:str1,str2,str3,str4是數(shù)組變量,它們有各自的內(nèi)存空間;而str5,str6,str7,str8是指針,它們指向相同的常量區(qū)域。
8.以下代碼中的兩個(gè)sizeof用法有問(wèn)題嗎?[C易]
void UpperCase( char str[] )
//將str中的小寫(xiě)字母轉(zhuǎn)換成大寫(xiě)字母
for( size_t i=0;i
if( 'a'<=str[i]&&str[i]<='z'str[i] -= ('a'-'A' );
char str[] ="aBcDe";
cout << "str字符長(zhǎng)度為: "<
UpperCase( str );
cout << str<
答:函數(shù)內(nèi)的sizeof有問(wèn)題。根據(jù)語(yǔ)法,sizeof如用于數(shù)組,只能測(cè)出靜態(tài)數(shù)組的大小,無(wú)法檢測(cè)動(dòng)態(tài)分配的或外部數(shù)組大小。函數(shù)外的str是一個(gè)靜態(tài)定義的數(shù)組,因此其大小為6,函數(shù)內(nèi)的str實(shí)際只是一個(gè)指向字符串的指針,沒(méi)有任何額外的與數(shù)組相關(guān)的信息,因此sizeof作用于上只將其當(dāng)指針看,一個(gè)指針為4個(gè)字節(jié),因此返回4。
注意:數(shù)組名作為函數(shù)參數(shù)時(shí),退化為指針.數(shù)組名作為sizeof()參數(shù)時(shí),數(shù)組名不退化,因?yàn)閟izeof不是函數(shù).
三、(一共十六題)
1.objective-c中是所有對(duì)象間的交互是如何實(shí)現(xiàn)的?(深圳皆凱科技有限公司筆試題)
2.如何將產(chǎn)品進(jìn)行多語(yǔ)言發(fā)布?
3.objective-c中是如何實(shí)現(xiàn)線程同步的?
4.編寫(xiě)函數(shù)_memmove說(shuō)明如下:實(shí)現(xiàn)C語(yǔ)言庫(kù)函數(shù)memmove的功能:將一塊緩沖區(qū)中的數(shù)據(jù)移動(dòng)到另一塊緩沖區(qū)中。可能有重復(fù)。
5.什么叫數(shù)據(jù)結(jié)構(gòu)?(面試順風(fēng)快遞iPhone開(kāi)發(fā))
6.編程中,保存數(shù)據(jù)有哪幾種方式?
7.Sizeof與strlen的區(qū)別和聯(lián)系?
答案:
1.sizeof操作符的結(jié)果類(lèi)型是size_t,它在頭文件中typedef為unsignedint類(lèi)型。該類(lèi)型保證能容納實(shí)現(xiàn)所建立的最大對(duì)象的字節(jié)大小。
2.sizeof是算符,strlen是函數(shù)。
3.sizeof可以用類(lèi)型做參數(shù),strlen只能用char*做參數(shù),且必須是以''\0''結(jié)尾的。
4.數(shù)組做sizeof的參數(shù)不退化,傳遞給strlen就退化為指針了。
5.大部分編譯程序在編譯的時(shí)候就把sizeof計(jì)算過(guò)了是類(lèi)型或是變量的長(zhǎng)度這就是sizeof(x)可以用來(lái)定義數(shù)組維數(shù)的原因
char str[20]="0123456789";//str是編譯期大小已經(jīng)固定的數(shù)組
int a=strlen(str); //a=10;//strlen()在運(yùn)行起確定
int b=sizeof(str); //而b=20;//sizeof()在編譯期確定
6.strlen的結(jié)果要在運(yùn)行的時(shí)候才能計(jì)算出來(lái),是用來(lái)計(jì)算字符串的實(shí)際長(zhǎng)度,不是類(lèi)型占內(nèi)存的大小。
7.sizeof后如果是類(lèi)型必須加括弧,如果是變量名可以不加括弧。這是因?yàn)閟izeof是個(gè)操作符不是個(gè)函數(shù)。
char c;
sizeof c;//變量名可以不加括弧
8.當(dāng)適用了于一個(gè)結(jié)構(gòu)類(lèi)型時(shí)或變量,sizeof返回實(shí)際的大小,當(dāng)適用一靜態(tài)地空間數(shù)組,sizeof歸還全部數(shù)組的尺寸。sizeof操作符不能返回動(dòng)態(tài)地被分派了的數(shù)組或外部的數(shù)組的尺寸
9.數(shù)組作為參數(shù)傳給函數(shù)時(shí)傳的是指針而不是數(shù)組,傳遞的是數(shù)組的首地址,如:
fun(char [8])
fun(char [])
都等價(jià)于fun(char *)
在C++里參數(shù)傳遞數(shù)組永遠(yuǎn)都是傳遞指向數(shù)組首元素的指針,編譯器不知道數(shù)組的大小
如果想在函數(shù)內(nèi)知道數(shù)組的大小,需要這樣做:
進(jìn)入函數(shù)后用memcpy拷貝出來(lái),長(zhǎng)度由另一個(gè)形參傳進(jìn)去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
我們能常在用到sizeof和strlen的時(shí)候,通常是計(jì)算字符串?dāng)?shù)組的長(zhǎng)度
看了上面的詳細(xì)解釋?zhuān)l(fā)現(xiàn)兩者的使用還是有區(qū)別的,從這個(gè)例子可以看得很清楚:
har
str[11]="0123456789";//注意這里str大小因該大于等于11,應(yīng)考慮'\0'在內(nèi),否則編譯器會(huì)報(bào)錯(cuò)
int a=strlen(str); //a=10;
>>>> strlen計(jì)算字符串的長(zhǎng)度,以結(jié)束符0x00為字符串結(jié)束。
int b=sizeof(str); //而b=11;
>>>> sizeof計(jì)算的則是分配的數(shù)組str[11]所占的內(nèi)存空間的大小,不受里面存儲(chǔ)的內(nèi)容改變。
上面是對(duì)靜態(tài)數(shù)組處理的結(jié)果,如果是對(duì)指針,結(jié)果就不一樣了
char* ss ="0123456789";
sizeof(ss)結(jié)果4===》ss是指向字符串常量的字符指針,sizeof獲得的是一個(gè)指針的之所占的空間,應(yīng)該是長(zhǎng)整型的,所以是4
sizeof(*ss)結(jié)果1===》*ss是第一個(gè)字符其實(shí)就是獲得了字符串的第一位'0'所占的內(nèi)存空間,是char類(lèi)型的,占了1位strlen(ss)= 10 >>>>如果要獲得這個(gè)字符串的長(zhǎng)度,則一定要使用strlen另外,下面的方法可以用于確定該靜態(tài)數(shù)組可以容納元素的個(gè)數(shù)int a[3]={1,2,3};
cout << sizeof a/sizeof ( typeid( a[0] ).name() );
8.什么是抽象類(lèi)?抽象類(lèi)有什么作用?能實(shí)例化嗎?
9.用Objective-C寫(xiě)冒泡法.
10.考察對(duì)@interface和@property的理解?
11.IPhone開(kāi)發(fā)中控制類(lèi)有什么作用?
12.線程中有哪些函數(shù)?寫(xiě)出來(lái)。
13.有沒(méi)有寫(xiě)過(guò)自定義的控件?
14.調(diào)用一個(gè)類(lèi)的靜態(tài)方法需不需要release?
15.do-while與while-do的區(qū)別?
16.寫(xiě)出幾個(gè)死循環(huán)?
答案:while(1){}
或者do{}while(1)
再或者for(;1;){}
還有g(shù)oto的
Loop:
…
goto Loop;
四、(一共十八題)
1.ObjC中,與alloc語(yǔ)義相反的方法是dealloc還是release?與retain語(yǔ)義相反的方法是dealloc還是release,為什么?需要與alloc配對(duì)使用的方法是dealloc還是release,為什么?
答案::alloc與dealloc語(yǔ)意相反,alloc是創(chuàng)建變量,dealloc是釋放變量。retain對(duì)應(yīng)release,retain保留一個(gè)對(duì)象。調(diào)用之后,變量的計(jì)數(shù)加1。或許不是很明顯,在這有例為證:
(void) setName : (NSString*)name {
[name retain];
[myname release];
myname = name;
}
我們來(lái)解釋一下:設(shè)想,用戶在調(diào)用這個(gè)函數(shù)的時(shí)候,他注意了內(nèi)存的管理,所以他小心的寫(xiě)了如下代碼:
NSString * newname =[[NSString alloc] initWithString: @"John"];
[aClass setName: newname];
[newname release];
我們來(lái)看一看newname的計(jì)數(shù)是怎么變化的。首先,它被alloc,count = 1;然后,在setName中,它被retain,count = 2;最后,用戶自己釋放newname,count = 1,myname指向了newname。這也解釋了為什么需要調(diào)用[myname release]。我們需要在給myname賦新值的時(shí)候,釋放掉以前老的變量。retain之后直接dealloc對(duì)象計(jì)數(shù)器沒(méi)有釋放。alloc需要與release配對(duì)使用,因?yàn)閍lloc這個(gè)函數(shù)調(diào)用之后,變量的計(jì)數(shù)加1。所以在調(diào)用alloc之后,一定要調(diào)用對(duì)應(yīng)的release。另外,在release一個(gè)變量之后,他的值仍然有效,所以最好是后面緊接著再var = nil。
在一個(gè)對(duì)象的方法里面:
2.self.name =“object”;和name=”object”有什么不同嗎?
答案::self.name = "object"會(huì)調(diào)用對(duì)象的setName()方法,name = "object"會(huì)直接把object賦值給當(dāng)前對(duì)象的name屬性。
[backcolor=transparent][backcolor=transparent]
3.這段代碼有什么問(wèn)題嗎:
[backcolor=transparent]@implementationPerson
[backcolor=transparent]-(void)setAge:(int)newAge {
[backcolor=transparent]self.age= newAge;
[backcolor=transparent]}
[backcolor=transparent]@end
答案:會(huì)進(jìn)入死循環(huán)。
4.什么是retain count?
答案::引用計(jì)數(shù)(ref count或者retain count)。對(duì)象的內(nèi)部保存一個(gè)數(shù)字,表示被引用的次數(shù)。例如,某個(gè)對(duì)象被兩個(gè)指針?biāo)赶颍ㄒ茫┠敲此膔etain count為2。需要銷(xiāo)毀對(duì)象的時(shí)候,不直接調(diào)用dealloc,而是調(diào)用release。release會(huì)讓retain count減1,只有retain count等于0,系統(tǒng)才會(huì)調(diào)用dealloc真正銷(xiāo)毀這個(gè)對(duì)象。
5.以下每行代碼執(zhí)行后,person對(duì)象的retain count分別是多少
Person *person = [[Personalloc] init]; count 1
[person retain]; count 2
[person release];count 1
[person release];retaincount = 1;
6.為什么很多內(nèi)置類(lèi)如UITableViewController的delegate屬性都是assign而不是retain的?
答案:會(huì)引起循環(huán)引用。
7.定義屬性時(shí),什么情況使用copy,assign,和retain。
答案:assign用于簡(jiǎn)單數(shù)據(jù)類(lèi)型,如NSInteger,double,bool,retain和copy用戶對(duì)象,copy用于當(dāng)a指向一個(gè)對(duì)象,b也想指向同樣的對(duì)象的時(shí)候,如果用assign,a如果釋放,再調(diào)用b會(huì)crash,如果用copy的方式,a和b各自有自己的內(nèi)存,就可以解決這個(gè)問(wèn)題。retain會(huì)使計(jì)數(shù)器加一,也可以解決assign的問(wèn)題。另外:atomic和nonatomic用來(lái)決定編譯器生成的getter和setter是否為原子操作。在多線程環(huán)境下,原子操作是必要的,否則有可能引起錯(cuò)誤的結(jié)果。加了atomic,setter函數(shù)會(huì)變成下面這樣:
if (property != newValue){[property release];property = [newValue retain];}
8.Autorelease的對(duì)象是在什么時(shí)候被release的?
答案:autorelease實(shí)際上只是把對(duì)release的調(diào)用延遲了,對(duì)于每一個(gè)Autorelease,系統(tǒng)只是把該Object放入了當(dāng)前的Autorelease pool中,當(dāng)該pool被釋放時(shí),該pool中的所有Object會(huì)被調(diào)用Release。對(duì)于每一個(gè)Runloop,系統(tǒng)會(huì)隱式創(chuàng)建一個(gè)Autorelease pool,這樣所有的release pool會(huì)構(gòu)成一個(gè)象CallStack一樣的一個(gè)棧式結(jié)構(gòu),在每一個(gè)Runloop結(jié)束時(shí),當(dāng)前棧頂?shù)腁utorelease pool會(huì)被銷(xiāo)毀,這樣這個(gè)pool里的每個(gè)Object(就是autorelease的對(duì)象)會(huì)被release。那什么是一個(gè)Runloop呢?一個(gè)UI事件,Timer call,delegate call,都會(huì)是一個(gè)新的Runloop。那什么是一個(gè)Runloop呢?一個(gè)UI事件,Timer call,delegate call,都會(huì)是一個(gè)新的Runloop。
9.這段代碼有什么問(wèn)題,如何修改
for (int i = 0; i
{
NSString *string = @”Abc”;
string = [stringlowercaseString];
string = [stringstringByAppendingString:@"xyz"];
NSLog(@“%@”, string);
}答案::會(huì)內(nèi)存泄露,
修改:
for(int i = 0; i<1000;i++){
NSAutoreleasePool * pool1 =[[NSAutoreleasePool alloc] init];
NSString *string =@"Abc";
string = [stringlowercaseString];
string = [stringstringByAppendingString:@"xyz"];
NSLog(@"%@",string);
[pool1 drain];
}
你的解決方法效率低,沒(méi)必要在每個(gè)循環(huán)都建立autorelease pool。在循環(huán)外面建一個(gè)就行了。
NSAutoreleasePool * pool1 =[[NSAutoreleasePool alloc] init];
for(int i = 0;i<1000;i++){
NSString *string =@"Abc";
string = [stringlowercaseString];
string = [stringstringByAppendingString:@"xyz"];
NSLog(@"%@",string);
}
[pool1 release];//[pool1
drain];效果相同,但我更喜歡release,看起來(lái)傳統(tǒng)一點(diǎn)
10.autorelease和垃圾回收機(jī)制(gc)有什么關(guān)系?答案::不懂
11.IPhone OS有沒(méi)有垃圾回收(gc)?沒(méi)有
12.什么是Notification?答案:觀察者模式,controller向defaultNotificationCenter添加自己的notification,其他類(lèi)注冊(cè)這個(gè)notification就可以收到通知,這些類(lèi)可以在收到通知時(shí)做自己的操作(多觀察者默認(rèn)隨機(jī)順序發(fā)通知給觀察者們,而且每個(gè)觀察者都要等當(dāng)前的某個(gè)觀察者的操作做完才能輪到他來(lái)操作,可以用NotificationQueue的方式安排觀察者的反應(yīng)順序,也可以在添加觀察者中設(shè)定反映時(shí)間,取消觀察需要在viewDidUnload跟dealloc中都要注銷(xiāo))。參考鏈接:http://useyourloaf.com/blog/2010/6/6/delegation-or-notification.html
13.什么時(shí)候用delegate,什么時(shí)候用Notification?答案:delegate針對(duì)one-to-one關(guān)系,并且reciever可以返回值給sender,notification可以針對(duì)one-to-one/many/none,reciever無(wú)法返回值給sender.所以,delegate用于sender希望接受到reciever的某個(gè)功能反饋值,notification用于通知多個(gè)object某個(gè)事件。
14.什么是KVC和KVO?答案:KVC(Key-Value-Coding)內(nèi)部的實(shí)現(xiàn):一個(gè)對(duì)象在調(diào)用setValue的時(shí)候,
(1)首先根據(jù)方法名找到運(yùn)行方法的時(shí)候所需要的環(huán)境參數(shù)。
(2)他會(huì)從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口。
(3)再直接查找得來(lái)的具體的方法實(shí)現(xiàn)。KVO(Key-Value-Observing):當(dāng)觀察者為一個(gè)對(duì)象的屬性進(jìn)行了注冊(cè),被觀察對(duì)象的isa指針被修改的時(shí)候,isa指針就會(huì)指向一個(gè)中間類(lèi),而不是真實(shí)的類(lèi)。所以isa指針其實(shí)不需要指向?qū)嵗龑?duì)象真實(shí)的類(lèi)。所以我們的程序最好不要依賴于isa指針。在調(diào)用類(lèi)的方法的時(shí)候,最好要明確對(duì)象實(shí)例的類(lèi)名。
15.Notification和KVO有什么不同?答:不知道
16.KVO在ObjC中是怎么實(shí)現(xiàn)的?答:不知道
17.ViewController的loadView, viewDidLoad, viewDidUnload分別是在什么時(shí)候調(diào)用的?在自定義ViewController的時(shí)候這幾個(gè)函數(shù)里面應(yīng)該做什么工作?
答案:viewDidLoad在view從nib文件初始化時(shí)調(diào)用,loadView在controller的view為nil時(shí)調(diào)用。此方法在編程實(shí)現(xiàn)view時(shí)調(diào)用,view控制器默認(rèn)會(huì)注冊(cè)memory warning notification,當(dāng)view controller的任何view沒(méi)有用的時(shí)候,viewDidUnload會(huì)被調(diào)用,在這里實(shí)現(xiàn)將retain的view release,如果是retain的IBOutlet view屬性則不要在這里release,IBOutlet會(huì)負(fù)責(zé)release。
18.ViewController的didReceiveMemoryWarning是在什么時(shí)候被調(diào)用的?默認(rèn)的操作是什么?答案:默認(rèn)調(diào)用[superdidReceiveMemoryWarning]
五、一共七題
1.Objective-C的內(nèi)存管理方式, NSAutoreleasePool的作用
2.寫(xiě)一個(gè)retain方式聲名屬性的setter方法
3.Objective-C與C的區(qū)別有哪些
4.列出你常用的幾個(gè)設(shè)計(jì)模式,列出如何在Objective-C中實(shí)現(xiàn)與應(yīng)用
5.drawRect,
lasyoutSubViews的區(qū)別
6.列舉Cocoa中常用的幾種多線程實(shí)現(xiàn),并談?wù)劧嗑€程安全問(wèn)題的幾種解決方案,什么地方會(huì)用到多線程
7.Socket連接相關(guān)庫(kù),TCP,UDP的連接方法,HTTP的幾種常用方式
六、一共四題
1.用Objective-C寫(xiě)冒泡法
2.Cocoa函數(shù)庫(kù)的使用
3.考察對(duì)線程的理解
4.考察對(duì)MVC的理解?模型—視圖—控制器
七、一共九題
1.Objective-C內(nèi)部的實(shí)現(xiàn)
2.CALayer和View的關(guān)系
3.http協(xié)議,tcp/ip
4.UITableView的那些元素是可以自定義的?
5.c語(yǔ)言的,定義變量,比如int,在什么情況下,其最大值是不同的
6.比較32位平臺(tái)和64位平臺(tái)不同
7.iPhone app為什么會(huì)被打回來(lái),如何避免??
8.為啥離開(kāi)團(tuán)隊(duì)?
八、一共十題
1.為什么很多內(nèi)置類(lèi)如UITableViewController的delegate屬性都是assign而不是retain?
會(huì)導(dǎo)致循環(huán)引用。
2.有如下一個(gè)類(lèi)定義
interface MyClass : NSObject
{}
@property(retain) NSString *myProp;
@end
請(qǐng)完成myProp屬性的set方法:
-(void)setMyProp:(NSString*)aProp
{
if(myProp!=aPtrop)
[myProp release]
myProp=[aProp retain ]
}
3.寫(xiě)出下面程序段的輸出結(jié)果
NSString *aStr = [[[NSString alloc]
initWithString:@”Hello World”] autoRelease];
NSMutableArray *aArray = [NSMutableArray array];
[aArray addObject:aStr];
NSLog(@”ref=%d”, [aStr retainCount])
4.簡(jiǎn)述Notification的工作機(jī)制。
5.有一個(gè)UIView對(duì)象aView,當(dāng)前大小為全屏。請(qǐng)編寫(xiě)代碼實(shí)現(xiàn)如下效果:將aView的寬和高各縮小為原來(lái)一半,中心點(diǎn)仍在屏幕中心,并在縮小的同時(shí)實(shí)現(xiàn)漸隱。
6.寫(xiě)出下面程序段的輸出結(jié)果
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"a stringvalue" forKey:@"akey"];
NSLog(@"%@", [dict objectForKey:@"akey"]);
[dict release];
7.@class關(guān)鍵字有什么作用
8.不使用繼承,為NSStirng類(lèi)添加新方法myPrint。
9.寫(xiě)出下面程序段的輸出結(jié)果
NSArray array = [NSArrayarrayWithObjects:@"one",@"two",@"three",nil];
NSLog(@"%@", [array objectAtIndex:1]);
NSLog(@"%@", [array objectAtIndex:3]);