1.objective-c常見面試題:
1、**OC **語言的基本特點
OC 語言是 C 語言的一個超集,只是在 C 的基礎之上加上了面向對象(oop) 的特性;
OC 與 Java 語言相同都是單繼承,這一點與 C++語言不同(多重繼承);OC 不支持命名空間機制,取而代之的是在類名之前添加前綴,以此來區分。
2、以下命名正確的是
(1)類(Person、person、ObjectAndKeys、personAndOther) (2)對象 (objectAndKeys、Person、_person、$dog) (3)實例變量 (_dog、^age、name、Name、)
3、數據類型和表達式
(1) inta=5,b=2,c=2,result,result=ab++-c;求result的值和b的值。
答:result 的值為 8,b 的值為3。根據運算符的優先級(乘法比加法的優先 級高),首先計算 ab,因為 b++,“++”在后面。因此,先計算 ab,其結果為 10,計算完成后 b 的結果++,因此b 的結果為3。最后與c 相減,result 的結果 為8。
(2)result= (b > a)? a++ : ((++c> a-b)? ++c : b++),求result,a,b,c 的值,假設 a、b、c的值分別為1、2、3。(右結合性;運算符號優 先級->結合性->順序)
答:運算符號相同,因此判斷運算符號的結合性。即表達式為:result = (b > a)? a++ :(++c > a-b)? ++c : b++),然后我們判斷表達是(b > a)是否為真。 因此,result 的結果為1,a、b、c 的值分別為 2、2、3。
(3)inta = 5, b = 12, c = 3, result = 0, d = 5, e = 2,result= a -= b /= c += d %= e;求result,a、b、c、d、e*。
答:運算符號相同,因此,判斷該運算符號的結合性。賦值運算符號為右結合, 因此,表達式從右開始計算。d %= 2,分解為d = d % e,d 值為 1;計算c += d, 同理,c值為4。再計算b /= c,b值為3;再計算a -= b,a值為2。最后將a 值賦值給 result。因此,result 的結果為2,a、b、c、d、e 的結果分別是 2、3、 4、1、2。(復合賦值運算符效率更高)
(4)如果第三題中 d為-5,求result。答:%(模運算符號)的符號取決與第一個數,因此,result 的值為-1,a、b、
c、d、e 的值分別為-1、6、2、-1、2。(5)假設 a、b、c 的值分別是4、5、6。那么result = a < b < c,求result 是多少?
答:result 值為 1。(6)解釋id類型
答:任意類型對象。程序運行時決定才對象的類型。 (7)解釋nil,發送消息時,程序是否會出現異常。
答:不會,在OC 語言中可以 nil 發送消息,而程序不會拋出異常,其結果是什么也不做。
4、流程控制語句
(1)**switch 語句每一case 都需要添加 break 語句嗎?答:switch 語句中的 break 語句不是必須的,此外,default 語句也不是必須
添加的。如果在某一個條件中添加(case 語句之后)break 語句,即當條件滿足 時,跳出 switch 語句。(2)do while 語句和 while 語句的區別,并寫出幾個死循環。
答:do while 語句至少執行一次循環體,而while 語句括號中的表達式為真, 才執行循環體。
while(1){ }、for(;)(3)switch **語句 **if **語句區別與聯系以及它的優勢在哪里
答:均表示條件的判斷,switch 語句表達式只能處理是整型、字符型和枚舉類 型,而選擇流程語句則沒有這樣的限制。但 switch 語句比選擇流程控制語句效 率更高。(4)int number = 26,k = 1,求 k 的值
do {k = number % 10;
number /= 10;} while(number);
答:do while 語句的特點是,循環體至少執行一次。程序執行到表達式 k=number%10,已知number 為26,又已知算術運算符比賦值運算符好優先級別高,因此先計算 number%10,其結果為 6;已知 k 為1,因此,k 的結果為6。number/=10,number 的值2。while 語句判斷表達式是否為真,此時,number 為 2。繼續執行循環體,此時number、k 的值分別為 2、6,2%10 的結果仍為 2,再與 k 相乘,其 k 的結果為12。程序執行到循環體第二行 number/10,此時 number 已為 10,因此,number 的結果為 0。while 表達式內條件為假,循環就此結束。因此,k 的值為 12。
5、寫出以下方法類型、方法名稱和返回值類型
(1)-(void)initWithName:(NSString)name andAge:(int) age;(2)+(Person)personName:(NSString)name; (3)-(void)setName:(NSString )name setAge:(int)agesetDelegate:(id)delegate;
(4)-(NSString)name;(5)+ (Kingdom *)shareKingdom; (6)+(Kingdom *)defaultKingdom;
6、創建一個這樣的 Person類,用類目的形式給**Person **添加一組方法(方法任意)、并且若干私有方法以及在 Person類中添加一個協議(手寫代碼)
.h文件#import @”Person.h”
@protocol PersonDelegate @required- (void)thisRequiredMethod;@optional
- (void)thisOptionalMethod; @end
@interface Person : NSObject { @private
NSString *_name;
NSInteger _age; } - (void)test;
- (void)test1:(int)arg1;
- (void)test1:(int)arg1 test2:(int)arg2; @end@interface Person (Create)- (id)initWithName:(NSString *)aName;- (id)initWithName:(NSString *)aName age:(int)age; + (id)personBorn; @end
.m文件
@interface Person () - (void)private1;- (void)private2; @end @implementation
- (void)test {}- (void)test1:(int)arg1 {}- (void)test1:(int)arg1 test2:(int)arg2 {} - (void)private1 {}- (void)private2 {}
- (id)initWithName:(NSString *)aName { self = [superinit];
if (self) {}return self;
}- (id)initWithName:(NSString *)aName age:(int)age {
...... }
- (id)personBorn {Person *person = [[Person alloc] init]; return [person autorelease];
} @end
7、協議的基本概念和協議中方法默認為什么類型
答:OC 中的協議是一個方法列表,且多少有點相關。它的特點是可以被任何 類使用(實現),但它并不是類(這里我們需要注意),自身不會實現這樣方法,
而是又其他人來實現。協議經常用來實現委托對象(委托設計模式)。如果一個類采用了一個協議,那么它必須實現協議中必須需要實現的方法,在 協議中的方法默認是必須實現(@required),添加關鍵字@optional,表明一旦
采用該協議,這些“可選”的方法是可以選擇不實現的。
8、**#include 與#import 的區別、#import 與@class **的區別
答:#include 和#import 其效果相同,都是查詢類中定義的行為(方法)。只 是后者不會引起交叉編譯,確保頭文件只會被導入一次。@class 的表明,只定義了類的名稱,而具體類的行為是不知道的,一般用于.h 文件,因此,@class 比#import 編譯效率更高。此外@class 和#import 的主要區別在于解決引用死鎖 的問題。
9、@public、@protected、@private它們的含義與作用
( 1) @public:答:對象的實例變量的作用域在任意地方都可以被訪問
( 2) @protected:答:對象的實例變量作用域在本類和子類都可以被訪問
( 3) @private:答:實例變量的作用域只能在本類(自身)中訪問
(4)通過指針運算符(->)能夠訪問到private方法嗎?**OC **語言中還提供 了哪些方式能直接和間接的訪問對象的實例變量?
答:不可以,可以通過合成存取器訪問實例變量,也可自己定義 setter 和getter 方法訪問實例變量,KVC(key value coding)——鍵值編碼,間接的方式訪問實 例變量。
10、簡述類目優點和缺點,如果覆蓋本類或者父類的方法,會出現什么問題?
答:(1)優點:不需要通過增加子類而增加現有類的行為(方法),且類目中的方法與原始類方法基本沒有區別;通過類目可以將龐大一個類的方法進行劃分,從而便于代碼的日后的維護、更新以及提高代碼的閱讀性。
(2)缺點:無法向類目添加實例變量,如果需要添加實例變量,只能通過 定義子類的方式;類目中的方法與原始類以及父類方法相比具有更高級別的優先 級,如果覆蓋父類的方法,可能導致 super 消息的斷裂。因此,最好不要覆蓋原 始類中的方法。
11、簡述內存管理基本原則
答:(1)如果使用alloc、copy(mutableCopy)或者 retian 一個對象時,你就 有義務,向它發送一條 release 或者autorelease 消息。其他方法創建的對象,不 需要由你來管理內存。
(2)向一個對象發送一條 autorelease 消息,這個對象并不會立即銷毀,而是將這個對象放入了自動釋放池,待池子釋放時,它會向池中每一個對象發送 一條 release 消息,以此來釋放對象。
(3)向一個對象發送 release 消息,并不意味著這個對象被銷毀了,而是 當這個對象的引用計數為 0 時,系統才會調用 dealloc 方法,釋放該對象和對象 本身它所擁有的實例。
12、在 objective c中是否支持垃圾回收機制? 答:OC是支持垃圾回收機制的(Garbagecollection簡稱GC),但是apple的
移動終端中,是不支持 GC 的,Mac 桌面系統開發中是支持的。 13、什么是**ARC 技術?與GC **是否相同?
答:ARC 是 AutomaticReference Counting 的簡稱,我們稱之為自動引用計數,
是在IOS 5之后推出的新技術,它與GC的機制是不同的。我們在編寫代碼時, 不需要向對象發送 release 或者 autorelease 方法,也不可以調用 delloc 方法, 編譯器會在合適的位置自動給用戶生成release 消息(autorelease),ARC 的特點是自動引用技術簡化了內存管理的難度。
14、什么是retain count答:每一個對象都默認有一個 retainCount 的屬性,數值的多少表示現在有幾
個實例正在引用它。當它為 0 時,系統會自動調用 dealloc 方法,將內存回收。15、寫出*@property (nonatomic ,retain) Person person;
**@synthesize person **具體實現,并指出其中含義。
非原子性事物
- (void)setPerson:(Person *)person {if (_person!= person){ [_person release]; _person = [person retain]; } }
- (Person )person { return _person; } 原子性事物- (void)setPerson:(Person)person {@synchronized(self) { if (_person!= person){
[_person release]; _person = [person retain]; }
} } - (Person *)person {
@synchronized(self) {
return _person; }
}
16、深、淺復制的基本概念以及他們的區別,可以用圖 來加以說明。
17、堆和棧的區別
答:(1)棧區(stack)由編譯器自動分配釋放 ,存放方法(函數)的參數值,局部變量的值等。先進后出。
(2)堆區(heap)一般由程序員分配釋放, 若程序員不釋放,程序結束時由OS回收。
(3)全局區(靜態區)(static),全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束后有系統釋放。
(4)文字常量區—常量字符串就是放在這里的。程序結束后由系統釋放。 (5)程序代碼區—存放函數體的二進制代碼。
18、用戶自定義了一個對象,如何實現拷貝(可變和不可變拷貝)
答:必須實現 copying 和mutableCopying 協議,表示返回一個不可變和可變的對象。否則,程序將會出現異常。-(id)copyWithZone:(NSZone *)zone{
Person *person = [[self Class] allocWithZone:zone];person ->age = self.age;person ->name = self.name;return person;
}- (id)mutableCopyWithZone(NSZone *)zone;
19、以下代碼有問題嗎?如果有,會出現什么問題
- (void) setName:(NSString *)name {
self.name = name; }
答:引起重復調用(自己調用自己)。
20、定義屬性時,什么時候用 assign、retain、**copy **以及它們的之間的區別
答:(1)assign:普通賦值,一般常用于基本數據類型,常見委托設計模式,以此來防止循環引用。(我們稱之為弱引用,weak)
(2)retain:保留計數,獲得到了對象的所有權。引用計數在原有基礎上 加1。
(3)copy:一般認為,是在內存中重新開辟了一個新的內存空間,用來
存儲新的對象,和原來的對象是兩個不同的地址,引用計數分別 1。但是當 copy 對象為不可變對象時,那么 copy 的作用相當于 retain。因為,這樣可以節約內 存空間。
21、解釋以下關鍵字,static、self、super用實例說明
答static: 靜態全局變量,持久性作用、存儲區域在靜態區域,它的生命周期 和應用進行綁定。程序結束時,由系統自動回收。
self:當前消息的接收者。 super:向父類發送消息。
22、解釋 self = [super init]方法
答:容錯處理,當父類初始化失敗,會返回一個 nil,表示初始化失敗。由于繼承的關系,子類是需要擁有父類的實例和行為的,因此,我們必須先初始化父 類,然后再初始化子類。
23、當我們釋放對象時,為什么需要調用[super dealloc]方法?
答:(1)因為,子類是繼承自父類,那么子類中有一些實例變量(對象),是繼承子父類的,因此,我們需要調用父類方法,將父類所擁有的實例進行釋放。
(2)先將子類所擁有的實例進行釋放,然后再釋放父類的。 24、objective-c有私方法么?私有變量呢?
答:是有的,我們稱之為延展。私有變量也是有的(@private)。25、以下每行代碼執行后,person對象的retain count分
別是多少?Person *person =[[Person alloc] init]; // 1
[person retain]; [person release]; [personrelease];
// 2 // 1
// 0
26、在某個方法中 self.name = _name、name = _name他 們有區別嗎,為什么?
答:是有區別的,前者是存在內存管理的,它會對_name 對象進行保留或者拷 貝操作,而后者是普通賦值。
27、假設我們寫了一個類的合成存取器,@property(nonatomic, copy) NSString name;@synthesizename;*
(1)NSStringaName = [NSString stringWithFormat:@”a”];person.name = aName 此時 name 的引用計數是幾,為什么,這么做
有什么好處?答:它的引用技術是 2,相當于 retain 操作。
(2)NSMutableStringaName = [NSMutableString stringWithFormat:@”a”];同上
答:它的引用技術是 1,真正意義上的拷貝。(3)返回這一個字符串的類型,是可變的嗎?如果不是,為什么,我們 又如何做?
答:不可變,因為合成存取器中用的 copy。如果,我們需要返回一個可變 的字符串時,那么必須自己實現 setter 和getter 方法。
28、自動釋放池是什么,如何工作
答:自動釋放池是 NSAutorelease 類的一個實例,當向一個對象發送 autorelease 消息時,該對象會自動入池,待池銷毀時,將會向池中所有對象發送一條 release 消息,釋放對象。[pool release]; [pool drain]表示的是池本身
不會銷毀,而是池子中的臨時對象都被發送release,從而將對象銷毀。 29、為什么delegate(代理)屬性都是assign 而不是retain
的? 答:防止循環引用,以至對象無法得到正確的釋放。
30、**iOS **開發中數據持久性,有哪幾種。 答:文件寫入、對象歸檔、sqlite3數據庫、coredata
31、對象歸檔的基本概念,以及它的特點是什么?
答:歸檔為對象的數據持久化提供了一種解決方法,它特點是給歸檔的對象進行加密,增強了數據的安全性。此外,自定義類的對象歸檔必須實現 NSCoding 協議。
32、什么是謂詞?答:cocoa 中提供了一個 NSPredicate 的類,該類主要用于指定過濾器的條件,
每一個對象通過謂詞進行篩選,判斷條件是否匹配。33、什么是 KVC 和KVO?以及它們之間的關系是什么
答:(1)KVC(鍵值編碼)是一種間接訪問對象實例變量的機制,該機制可以 不通過存取方法就可以訪問對象的實例變量。非對象類型的變量將被自動封裝或 者解封成對象。此外,使用KVC 能夠簡化代碼。我們需要注意 KVC 有兩個較為 明顯的缺點,一旦使用 KVC 你的編譯器無法檢查出錯誤,即不會對設置的鍵、 鍵路徑進行錯誤檢查,且執行效率要低于(雖然效率已經很高,你已經感覺不到)合成存取器方法和自定的 setter 和 getter 方法。因為使用 KVC 鍵值編碼,它必 須先解析字符串,然后在設置或者訪問對象的實例變量。
(2)KVO(鍵值觀察)是一種能使得對象獲取到其他對象屬性變化的通知
機制。(3)實現 KVO 鍵值觀察模式,被觀察的對象必須使用KVC 鍵值編碼來修
改它的實例變量,這樣才能被觀察者觀察到。因此,KVC 是KVO 的基礎或者說 KVO 的實現是建立在 KVC 的基礎之上的。
34、在 objective c中如何實現KVO
答:(1)注冊觀察者(這里我們需要注意,觀察者和被觀察者不會被保留也不 會被釋放)
- (void)addObserver:(NSObject *)observerforKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void )context;
(2)接收變更通知- (void)observeValueForKeyPath:(NSString)keyPath
ofObject:(id)object change:(NSDictionary *)changecontext:(void *)context;
(3)移除對象的觀察者身份-(void)removeObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath;
35、當我們釋放我們的對象時,為什么需要調用[super dealloc]方法,它的位置又是如何的呢?
答:因為子類的某些實例是繼承自父類的,因此需要調用[super dealloc]方法, 來釋放父類擁有的實例,其實也就是子類本身的。一般來說我們優先釋放子類擁 有的實例,最后釋放父類所擁有的實例。
36、以下代碼會出項問題嗎?如果有,我們又該如何修 改?
@property (nonatomic, copy) NSMutableString *name;@synthesize name = _name;
self.name = [NSMutableStringstringWithFormat:@"..xyz"]; [self.name insertString:@"abc"atIndex:0];
答:不可變字符串不可以被修改,可以通過自定義 set 方法,將字符串的拷貝 改為可變的拷貝。
37、當我們將一個對象加入自動釋放池時,該對象何時 被銷毀
答:我們在 application kit 應用程序中,自動釋放池中的臨時對象被銷毀的時間時,一個事件循環結束后。注意自動釋放池沒有被釋放,而是被排空了,向池發送了 drain 消息。
38、當我們調用一個靜態方法時,需要對對象進行release嗎?
答:不需要,靜態方法(類方法)創建一個對象時,對象已被放入自動釋放池。在池被釋放時,很有可能被銷毀
。
39、什么叫鍵路徑?
答:在一個給定的實體中,同一個屬性的所有值具有相同的數據類型。 鍵-值編碼技術用于進行這樣的查找—它是一種間接訪問對象屬性的機制。 鍵路徑是一個由用點作分隔符的鍵組成的字符串,用于指定一個連接在一起的對象性質序列。第一個鍵的性質是由先前的性質決定的,接下來每個鍵的值也是相
對于其前面的性質。鍵路徑使您可以以獨立于模型實現的方式指定相關對象的性 質。通過鍵路徑,您可以指定對象圖中的一個任意深度的路徑,使其指向相關對 象的特定屬性。
40、以下代碼存在內存泄露嗎?如果有,如何去修改
self.object = [NSObject alloc] init]; self.object =[NSObject object] retain]; self.object = [NSObject object];
- (void)dealloc {
self.object = nil;
[super dealloc]; }
41、循環引用是什么,如何解決這樣的問題
答:對象 a 創建并引用到了對象 b;對象 b 創建并引用到了對象 c;對象 c 創建并引用到了對象 b。這時候 b 和 c 的引用計數分別是 2 和1。
當a 不再使用b,調用 release 釋放對b 的所有權,因為 c 還引用了b,所以 b 的引用計數為 1,b 不會被釋放。
b 不釋放,c 的引用計數就是 1,c 也不會被釋放。從此,b 和c 永遠留在內存 中。
這種情況,必須打斷循環引用,通過其他規則來維護引用關系。我們常見的 delegate 往往是 assign 方式的屬性而不是 retain 方式的屬性, 賦值不會增加引用計數,就是為了防止 delegation 兩端產生不必要的循環引用。
42、isMemberOfClass和isKindOfClass聯系與區別
答:兩者都能檢測一個對象是否是某個類的成員, 兩者之間的區別是:
isKindOfClass 不但可以用來確定一個對象是否是一個類的成員,也可以用來確 定一個對象是否是派生自該類的類的成員 ,而 isMemberOfClass 做不到后一點。
如 ClassA 派 生 自 NSObject 類 , ClassA*a = [ClassA alloc] init]; [a isKindOfClass:[NSObject class]] 可以檢查出 a是否是 NSObject派生類 的成員,但 isMemberOfClass 做不到。
2.面試題
1.簡述OC中內存管理機制
1.1 OC的內存管理機制是自動引用計數,內存管理的原則是誰開辟誰釋放,有retain的地方就要有release
1.2 內存管理分為ARC和MRC,在MRC下我們需要手動管理內存,需要使用到retain/copy/release/autorelease等方法實現內存管理。ARC下則一般不需要我們手動管理,系統會在適當的位置加上內存管理關鍵字。
1.3 retain是引用計數+1,在內存管理中,要記得內存管理原則:誰開辟誰釋放,有retain就要有release. release是引用計數-1.alloc匹配的是dealloc,alloc是開辟內存空間,dealloc是銷毀所開辟的內存,有開辟就要有 銷毀.
2.readwrite,readonly,assign,retain,copy,nonatomic、atomic、strong、weak屬性的作用?
readWrite讀寫特性,可讀可寫.
readonly只讀,只有getter,沒有setter.
assign一般用于基本數據類型和ID類型.
copy拷貝,一般用于 NSString.分為深拷貝和淺拷貝,深拷貝拷貝的是對象,淺拷貝拷貝的是指針.nonatomic非原子性,不考慮線程安全,優點是效率高.
atomic原子性,有點是線程安全,缺點是效率低.
strong強引用,和MRC下的retain一樣.weak弱引用,類似MRC下的assign.但是要注意的是strong和weak都是修飾對象類型的屬性的,不能修飾基本數據類型.ARC下仍然使用assign修飾基本數據類型.
3.關于iOS多線程問題
仔細閱讀:http://www.cocoachina.com/ios/20150731/12819.html
4.提升UITableView性能的幾點建議
仔細閱讀:http://www.cocoachina.com/ios/20150729/12795.html
- 線程同步和異步的區別?
同步:一個線程要等待上一個線程執行完之后才能執行當前的線程,生活中的例子(上廁所)。
異步:同時去做兩件或者多件事。比如邊聽歌邊看報。
7.堆和棧的區別?
棧區(stack)--由編譯器自動分配釋放,存放函數的參數值、局部變量的值。先進后出
堆區(heap)--一般由程序員分配釋放。先進先出
全局區(靜態區)(static)--全局變量和靜態變量。程序結束后由系統釋放。
文字常量區--常量字符串存放在這里。程序結束后由系統釋放。
程序代碼區—存放函數體的二進制文件。
- iOS類是否可以多繼承?
不可以,可以通過delegate和protocol和類別來實現類似多繼承。
9.iOS本地數據存儲都有哪幾種方式?iOS如何實現復雜對象的存儲?
- Write寫入方式:永久保存在磁盤中。但是只支持NSString、NSData、NSArray、NSDictionary。 2.NSKeyedArchiver(歸檔)采用歸檔的形式來保存數據,該數據對象需要遵守NSCod-ing協議,并且該對象對應的類必須提供 encodeWithCoder:和initWithCoder:方法。
3.SQLite(FMDB)注意FMDB不是數據庫,而是一個SQLITE管理框架.
4.CoreData切記coredata不是數據庫,他的存儲核心思想是托管對象,只是咱們經常用的存儲文件為SQLite.還可以用XML,二進制等方式.
10.iOS的動態性
1.動態類型。如id類型。實際上靜態類型因為其固定性和可預知性而使用得更加廣泛。靜態類型是強類型,而動態類型屬于弱類型。運行時決定接收者。
- 動態綁定。讓代碼在運行時判斷需要調用什么方法,而不是在編譯時。與其他面向對象語言一樣,方法調用和代碼并沒有在編譯時連接在一起,而是在消息發送時才進行連接。運行時決定調用哪個方法。
- 動態載入。讓程序在運行時添加代碼模塊以及其他資源。用戶可以根據需要加載一些可執行代碼和資源,而不是在啟動時就加載所有組件。可執行代碼中可以含有和程序運行時整合的新類。
11.深拷貝和淺拷貝的理解?
深拷貝拷貝的是內容,淺拷貝拷貝的是指針。深拷貝和淺拷貝最大的區別就是子類對象的地址是否改變,如果子類對象的地址改變那么就是深拷貝。
12.什么是安全釋放
在對象dealloc中release之后再把指針置為nil
13.怎樣實現一個singleton。
+(ZMYSingleton)sharedInstance{
staticLOSingletonsharedInstance=nil;
staticdispatch_once_tonceToken; //鎖
dispatch_once(&onceToken,^{
//最多調用一次
sharedInstance=[[ZMYSingletonalloc]init];
});
return sharedInstance;
}
13.RunLoop是什么?
一個RunLoop就是一個事件處理的循環,用來不停的調 度工作以及處理輸入時間。使用runloop的目的是讓你的線程在有工作的時候忙于工作,而沒工作的時候處于休眠狀態。runloop的設計是為了減少 cpu無謂的空轉。每個開辟的線程都有一個Runloop,主線程的Runloop時默認開啟的,咱們手動開辟的子線程Runloop是默認不開啟 的,如果需要開啟,需要調用API[[NSRunloopcurrentRunloop]run]開啟.最常見的需要開啟Runloop的是在 子線程里面調用計時器(NSTimer),如果不開啟runloop循環方法就不能正常執行.
14.寫一個標準宏MIN,這個宏輸入兩個參數并返回較小的一個?
definekMIN(X,Y)((X)>(Y))?(Y):(X)
15.簡述應用程序按Home鍵進入后臺時的生命周期,以及從后臺回到前臺時的生命周期?
進入后臺生命周期走:
-(void)applicationWillResignActive:(UIApplication)application;
-(void)applicationDidEnterBackground:(UIApplication)application;
回到前臺生命周期走:
-(void)applicationWillEnterForeground:(UIApplication)application;
-(void)applicationDidBecomActive:(UIApplication)application;
16.ViewController的loadView,viewDidLoad,viewWillAppear,viewDidUnload,dealloc、init分別是在什么時候調 用的?在自定義ViewController的時候這幾個函數里面應該做什么工作?
loadView:沒有正在使用nib視圖頁面,子類將會創建自己的自定義視圖層
viewDidLoad:試圖被加載后調用
viewWillAppear:試圖即將出現的時候調用
viewDidUnload:當系統內存吃緊的時候會調用該方法,釋放掉當前未在window中顯示的試圖和對應的控制器
17.描述應用程序的啟動順序。
1、程序入口main函數創建UIApplication實例和UIApplication代理實例
2、在UIApplication代理實例中重寫啟動方法,設置第一ViewController
3、在第一ViewController中添加控件,實現對應的程序界面。
18.為什么寫代理的屬性都是assign而不是retain?請舉例說明。
防止循環引用,
Teacherteacher=[[Teacheralloc]init];
Studentstudent=[[Studentalloc]init];t
eacher.delegate=student;
student.delegate=teacher;
在teacher中dealloc會release當前的Delegate,就會觸發student對象release,繼而也會導致student執行dealloc,在student中也會release自己的delegate,產生循環了。
19.UIImage初始化一張圖片有幾種方法?簡述各自的優缺點。
1、從資源讀取,這個方法的圖片是從緩存里面獲取 的,先在緩存里面查看是不是有這個圖片,沒有的話將圖片添加進緩存再使用.有的話直接使用緩存里面的.如果這張圖片用的次數比較多的話,建議使 用這種方式.缺點是效率低下.UIImageimage=[UIImageimageNamed:@”1.png”];
2.從手機本地讀取,比較第一種方式,這個事直接加 載圖片的.所以建議在圖片使用率低的圖片時使用這個方法. //讀取本地圖片非resourceNSStringaPath3=[NSStringstringWithFormat:@"%@/Documents/%@.jpg",NSHomeDirectory(),@"test"];[UIImageimageWithContentsOfFile:aPath3]
20.這段代碼有什么問題嗎:
@implementationPerson
-(void)setAge:(int)newAge{
self.age=newAge;
}
@end
死循環
21.用OC寫一個冒泡排序
NSMutableArray*array = [NSMutableArrayarrayWithArray:@[@"3",@"1",@"10",@"5",@"2",@"7",@"12",@"4",@"8"]];
for (int i =0; i < array.count;i ++) {
for (intj =0; j < array.count-1 - i; j++) {
if([[arrayobjectAtIndex:j]integerValue] > [[arrayobjectAtIndex:j +1]integerValue]) {
[arrayexchangeObjectAtIndex:jwithObjectAtIndex:j +1];
}
}
}
NSLog(@"%@",array);
22.簡述你對UIView、UIWindow和CALayer的理解
UIView繼承于UIResponder,UIResponder繼承于NSObject,UIView可以響應用戶事件。
CALayer繼承于NSObject,所以 CALayer不能響應事件。 UIView構建界面,UIView側重于對內容的管理,CALayer側重于對內容的繪制。 UIView是用來顯示內容的,可以處理用戶事件;CALayer是用來繪制內容的,對內容進行動畫處理,依賴與UIView來進行顯示,不能處理用戶事 件。
23.frame和bounds區別:
仔細閱讀:http://blog.csdn.net/mad1989/article/details/8711697
24.寫一個完整的代理
25.分析json、xml的區別?json、xml解析方式的底層是如何處理的?
XML是標準通用標記語言(SGML)的子集,非常適合Web傳輸。XML提供統一的方法來描述和交換獨立于應用程序或供應商的結構化數據。
JSON(JavaScriptObjectNotation)一種輕量級的數據交換格式,具有良好的可讀 和便于快速編寫的特性。可在不同平臺之間進行數據交換。JSON采用兼容性很高的、完全獨立于語言文本格式,同時也具備類似于C語言的習慣(包括C, C++,C#,Java,JavaScript,Perl,Python等)體系的行為。這些特性使JSON成為理想 的數據交換語言。
26.ViewController的didReceiveMemoryWarning是在什么時候被調用的?默認的操作是什么?
didReceiveMemoryWarning在出現內存警告的時候執行該方法,在該方法里面釋放掉暫時沒使用的可重用的對象。這個方法不能手動調用.
27.面向對象的三大特征,并作簡單的介紹
封裝、繼承、多態。
封裝:是把客觀事物封裝成抽象的類,隱藏內部的實現,對外部提供接口。
繼承:可以使用現有類的所有功能,并且在無需重新編寫原來的類的情況下對這些功能進行擴展。
多態:不同的對象以自己的方式響應相同的的消息的能力叫做 多態,或者說父類指針指向子類對象<如UITableView的,cellForRow方法,返回值類型是UITbaleViewCell,但是你 返回的cell可以是你自定義的cell,在比如多個類里面都有同一個方法>
28.簡單說一下懶加載
懶加載,又稱為延遲加載。通常用法,你有一個UITextField類型的property,簡單定義為userNameTextField,但是你不在初始化方法里為其alloc/init,它 就只是一個指針,不會占用內存。在訪問器里判斷此property的指針是否為空,若為空,就alloc/init,這時才真正生成這個對象除非這個對 象被使用,否則它永遠不會真正生成,也就不會占用內存。
29.分別描述類目(categories)和延展(extensions)是什么?以及兩者的區別?繼承和類目在實現中有何區別?為什么Category只能為對象添加方法,卻不能添加成員變量?
category類目:在不知道源碼的情況下為一個類擴展方法,
extension:為一個類聲明私有方法和變量。 繼承是創建了一個新的類,而類別只是對類的一個擴展,還是之前的類。 類目的作用就是為已知的類添加方法。
-
import、#include和@class有什么區別
includec語言中引入一個頭文件,但是可能出現交叉編譯,
OC里面已經沒有這個方式引入頭文件了,統一使用#import
import在OC中引入自己創建的頭文件
import””是引入自己創建類的頭文件
import<>是引入系統類的頭文件
import不會出現交叉編譯
@class對一個類進行聲明,告訴編譯器有這個類,但是類的定義什么的都不知道.
31.談談你對MVC的理解?為什么要用MVC?在Cocoa中MVC是怎么實現的?你還熟悉其他的OC設計模式或別的設計模式嗎?
MVC是Model-VIew-Controller,就 是模型-視圖-控制器,MVC把軟件系統分為三個部分:Model,View,Controller。在cocoa中,你的程序中的每一個 object(對象)都將明顯地僅屬于這三部分中的一個,而完全不屬于另外兩個。model數據模型,view是對這些數據的顯 示,viewcontroller就是把model拿到view中顯示,起到model和view之間橋梁的作用。MVC可以幫助確保幫助實現程序最大程 度的可重用性。各MVC元素彼此獨立運作,通過分開這些元素,可以構建可維護,可獨立更新的程序組建,提高代碼的重用性.
單例模式,delegate設計模式,target-action設計模式
32.字符串替換方法:
[stringstringByReplacingOccurrencesOfString:@"png"withString:@""]
33.對于語句NSString*testObject=[[NSDataalloc]init]; testObject在編譯時和運行時分別是什么類型的對象?
編譯的時候是NSString類型,運行的時候是NSData類型
34.什么是沙盒(sandbox)?沙盒包含哪些文件,描述每個文件的使用場景。如何獲取這些文件的路徑?如何獲取應用程序包中文件的路徑?
iOS應用程序只能在為該改程序創建的文件系統中讀取文 件,不可以去其它地方訪問,此區域被成為沙盒,所以所有的非代碼文件都要保存在此,例如圖像,圖標,聲音,映像,屬性列表,文本文件等。 默認情況下,每個沙盒含有3個文件夾:Documents,Library和tmp。 Documents:蘋果建議將程序中建立的或在程序中瀏覽到的文件數據保存在該目錄下,iTunes備份和恢復的時候會包括此目錄 Library:存儲程序的默認設置或其它狀態信息;
Library/Caches:存放緩存文件,iTunes不會備份此目錄,此目錄下文件不會在應用退出刪除
tmp:提供一個即時創建臨時文件的地方。
iTunes在與iPhone同步時,備份所有的Documents和Library文件。
iPhone在重啟時,會丟棄所有的tmp文件。
- isKindOfClass、isMemberOfClass作用分別是什么?
-(BOOL)isKindOfClass:classObj判斷是否是這個類或者是這個類子類的實例
-(BOOL)isMemberOfClass:classObj判斷是否是這個類的實例
36.http://blog.csdn.net/huifeidexin_1/article/details/7566226 - UITableView –UIScrollView –UIView – UIResponder - NSObject
答:Grand CentralDispatch簡稱GCD解決多核并行運算的一種方案
看代碼就行:
// Grand CentralDispatch簡稱GCD技術
// Do any additional setup afterloading the view.
//dispatch_queue_tnewDispath =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//dispatch_async(newDispath,^{
//[selfdownloadImage];
// });
//#defineDISPATCH_QUEUE_PRIORITY_HIGH2
//#defineDISPATCH_QUEUE_PRIORITY_DEFAULT 0
//#defineDISPATCH_QUEUE_PRIORITY_LOW(-2)
//#defineDISPATCH_QUEUE_PRIORITY_BACKGROUNDINT16_MIN
/*dispatch queue分為下面三種:
- Serial:又稱為private dispatch queues,同時只執行一個任務。Serial queue通常用于同步訪問特定的資源或數據。當你創建多 個Serial queue時,雖然它們各自是同步執行的,但Serial queue與Serial queue之間是并發執行的。
- Concurrent: 又稱為global dispatch queue,可以并發地執行多個任務,但是執行完成的順序是隨機的。
- Maindispatchqueue它是全局可用的serial queue,它是在應用程序主線程上執行任務的
*/
// 一般GCD 可以如下操作
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
// 耗時的操作
dispatch_async(dispatch_get_main_queue(),^{
// 更新界面
});
});
[selfexampleDispatch];
/*
*系統給每一個應用程序提供了三個concurrent dispatch queues。
*這三個并發調度隊列是全局的,它們只有優先級的不同。
*因為是全局的,我們不需要去創建。我們只需要通過使用函數dispath_get_global_queue去得到隊列
*/
dispatch_queue_tglobalQ =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
NSLog(@"global:%p",globalQ);
dispatch_queue_tmainQ =dispatch_get_main_queue();
NSLog(@"mainQ:%p",mainQ);
/*
*雖然dispatch queue是引用計數的對象,但是以上兩個都是全局的隊列,不用retain或release。
*/
/*
*dispatch_group_async可以實現監聽一組任務是否完成,完成后得到通知執行其他的操作。
*這個方法很有用,比如你執行三個下載任務,當三個任務都下載完成后你才通知界面說完成的了。
*/
timeInt = 0;
[NSTimerscheduledTimerWithTimeInterval:1
target:self
selector:@selector(checkingTime)
userInfo:nil
repeats:YES];
[selfexampleDispath_group];
/*dispatch_barrier_async的使用
*dispatch_barrier_async是在前面的任務執行結束后它才執行,而且它后面的任務等它執行完成之后才會執行
*/
[selfexampleDispatch_barrier];
/*dispatch_apply
*執行某個代碼片段N次。
*/
dispatch_apply(5,globalQ, ^(size_t index) {
// 執行5次
});
- 該問題涉及編譯器的“內存對齊”問題:
現代計算機中內存空間都是按照byte(字節)劃分的,從 理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定變量的時候經常在特定的內存地址訪問,這就需要各類型數據按照一定的規則 在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
對齊的作用和原因:各個硬件平臺對存儲空間的處理上有很大 的不同。一些平臺對某些特定類型的數據只能從某些特定地址開始存取。其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺的要求對數據存放進行 對齊,會在存取效率上帶來損失。比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設為32位)如果存放在偶地址開始的地方,那么一個讀周期就 可以讀出,而如果存放在奇地址開始的地方,就可能會需要2個讀周期,并對兩次讀出的結果的高低字節進行拼湊才能得到該int數據。顯然在讀取效率上下降很 多。這也是空間和時間的博弈。
通常,我們寫程序的時候,不需要考慮對齊問題。編譯器會替我們選擇適合目標平臺的對齊策略。當然,我們也可以通知給編譯器傳遞預編譯指令而改變對指定數據的對齊方法。
但是,正因為我們一般不需要關心這個問題,所以因為編輯器對數據存放做了對齊,而我們不了解的話,常常會對一些問題感到迷惑。最常見的就是struct數據結構的sizeof結果,出乎意料。
對于結構體來說,按成員中所占字節最大的是float類型,占用4個字節,一共有3個成員,所以總的占用字節為:4*3=12.可通過編譯器命令來設定:
progmapack(2)
40.TCP:TransmissionControlProtocol傳 輸控制協議TCP是一種面向連接(連接導向)的、可靠的、基于字節流的運輸層(Transportlayer)通信協議,由IETF的RFC793說 明(specified)。UDP是UserDatagramProtocol的簡稱,中文名是用戶數據包協議,是OSI參考模型中一種無連接 的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務,IETFRFC768是UDP的正式規范。
面向連接:是指通信雙方在通信時,要事先建立一條通信線路,其有三個過程:建立連接、使用連接和釋放連接。電話系統是一個面向連接的模式,撥號、通話、掛機;TCP協議就是一種面向連接的協議。
面向無連接:是指通信雙方不需要事先建立一條通信線路,而是把每個帶有目的地址的包(報文分組)送到線路上,由系統自主選定路線進行傳輸。郵政系統是一個無連接的模式,天羅地網式的選擇路線,天女散花式的傳播形式;IP、UDP協議就是一種無連接協議。
- 注意問的是應用層協議,有些同學直接答了七層模型。
在開放系統互連(OSI)模型中的最高層,為應用程序提供服務以保證通信,但不是進行通信的應用程序本身。
Telnet協議是TCP/IP協議族中的一員,是Internet遠程登陸服務的標準協議和主要方式。它為用戶提供了在本地計算機上完成遠程主機工作的能力。
FTP文件傳輸協議是TCP/IP網絡上兩臺計算機傳送文件的協議,FTP是在TCP/IP網絡和INTERNET上最早使用的協議之一,它屬于網絡協議組的應用層。
超文本傳輸協議(HTTP-Hypertexttransferprotocol)是分布式,協作式,超媒體系統應用之間的通信協議。是萬維網(worldwideweb)交換信息的基礎。
SMTP(SimpleMailTransferProtocol)即簡單郵件傳輸協議,它是一組用于由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式,它幫助每臺計算機在發送或中轉信件時找到下一個目的地。
時間協議(TIMEprotocol)是一個在RFC868內定義的網絡協議。它用作提供機器可讀的日期時間資訊。
DNS是域名系統 (Domain Name System) 的縮寫,是因特網的一項核心服務,它作為可以將域名和IP地址相互映射的一個分布式數據庫。
SNMP(Simple Network ManagementProtocol,簡單網絡管理協議)的前身是簡單網關監控協議(SGMP),用來對通信線路進行管理。
TFTP(Trivial File Transfer Protocol,簡單文件傳輸協議)是TCP/IP協議族中的一個用來在客戶機與服務器之間進行簡單文件傳輸的協議,提供不復雜、開銷不大的文件傳輸服務。端口號為69。
42.static關鍵字的作用
靜態全局變量
優點:
1、節省內存。靜態變量只存儲一處,但供所有對象使用。
2、它的值是可以更新的。
3、可提高時間效率。只要某個對象對靜態變量更新一次,所有的對象都能訪問更新后的值。
43.iOS系統框架分為幾層,分別是什么
程序開發提供了各種有用的框架,并且大部分與用戶界面有關,本質上來說它負責用戶在iOS設備上的觸摸交互操作。