IOS面試攻略

IOS面試攻略(1.0)  

2013-10-13 20:58:09|  分類: IOS面試 |  標籤:ios知識點總彙  ios面試  |舉報|字號 訂閱html

 
 

來自:伊甸網java

 

 

@ios

看到這個關鍵字,咱們就應該想到,這是Object-C對C語言的擴展,例如@interface XXX。c++

@interface程序員

聲明類web

@implementation面試

實現類objective-c

@protocol算法

聲明協議sql

@optional

與@protocol配合使用,說明協議中的某個或者某幾個方法能夠不實現

@required

與@protocol配合使用,說明協議中的某個方法或者某幾個方法必須實現

@end

與@interface ,@implementation,@protocol配合使用,表明聲明或者實現結束

@encode

@encode爲編譯器宏,它能夠將類型轉換爲相應的字符串(const char *)。

id

id是指向Objective-C類對象的指針,它能夠聲明爲任何類對象的指針,當在Objective-C中使用id時,編譯器會假定你知道id指向哪一個類的對象。與void*是不一樣的是,void*編譯器不知道也不假定指向任何類型的指針。

nil

定義爲一個常量,若是一個指針的值爲nil,表明這個指針沒有指向任何對象。

self

在Objective-C中,關鍵字self與c++中this是同一律念,就是類對象自身的地址,經過self能夠調用本身的實例變量和方法

Super

當子類須要調用父類的方法時,會用到Super關鍵字. Super指向的是父類的指針,子類重寫父類的方法時,調用父類的方法是一個比較好的習慣。由於當咱們不知道父類在該方法中實現的功能時,若是不調用父類的方法,有可能咱們重寫的方法會失去該功能,這是咱們不肯意看到的狀況。

NSNull

NSNull是沒有的意思,若是一個字典的值爲NSNull,那說明與該值對應的Key是沒有值的,例如Key爲address,說明與address對應的是值是沒有。

self super class public protected private id

[self class] [super class]  selector

objective-c runtime reference

標準用法

self = [super init]

new

1 Objective-C有一個特性,就是能夠把類當成對象來發送消息,這種用法一般用於新建對像時,例如 XXX *object = [XXX new];

類方法 +

若是想聲明屬於類而不屬於類對象的方法,用+。+用來修飾類的方法,使用+修飾的類方法,是整個類的方法,不屬於哪個類對象,這與C++中的static在類中使用的概念同樣,

%@

在NSLog中,使用%@表示要調用對象的description方法。

概念

是一種結構,它表示對象的類型,就像int與 char 同樣,也能夠聲明類的變量(對像)

實例化

爲類的對象分配內存和初始化,達到能夠使用該 類對象的目的。

對象(實例)

類的實例化後的產物

消息

在 Object-C中,類的對象執行的操做,是經過給該類或者該類對象發送消息實現,如:[object func];就是給object對象發送 func消息,相似C++中的方法調用。給object對象發送func消息後,object對象查詢所屬類的func方法執行。

方法調度

當向一個對象發送消息時(調用方法),這個方法是怎麼被調用的呢?這就依賴於方法高度程序,方法調度程序查找的方法以下:

在本類的方法中,找被調用的方法,若是找到了,就調用,若是找不到被沿着繼承路徑去查找,從哪一個類找到,就調用哪一個類的方法,若是到最根上的類仍是沒有找到,那編譯就會出錯。

繼承與複合

在Objective-C中支持繼承,但只是支持單一繼承(有且只有一個父類有),若是想使用多繼承的特性,能夠使用分類和協議技術。

繼承是is-a,複合是has-a。複合是經過包含指向對象的指針實現的,嚴格意義上講,複合是針對於對象間來講,對於基本數據類型來講,它們被認爲是對象的一部分。

裝箱與拆箱

因爲NSArray,NSDirectory等類不能直接存儲基本數據類型,因此要想在NSArray\NSDirectory中使用基本數據類型,就得使用裝箱與拆箱。

在Objective-C中,能夠使用NSNumber和NSValue來實現對數據類型的包裝,NSNumber能夠實現對基本數據類型的包裝,NSValue能夠實現對任意類型數據的包裝。

將基本類型封裝成對象叫裝箱,從封裝的對象中提取基本類型叫拆箱(取消裝箱),其它語言如Java原生支持裝箱與拆箱,Ojbective-C不支持自動裝箱與拆箱,若是須要得須要本身來實現裝箱與拆箱。

存取方法

在 使用類對象的實例變量(成員數據)時,不要直接使用對象中的實例,要使用存以方法來獲取或者修改實例,既setter和getter,在 Cocoa中, 存取方法有命名習慣,咱們得符合這種習慣,以便於與其它團隊成員合做。setter方法是修改或者設置實例值,命名習慣爲set+實例名,例有一個類有 path實例變量,那setter命名爲setPath,getter命名爲Path,爲何不是getPath,由於get在Cocoa中有特殊的含 義,這個含義就是帶有get的方法就意味着這個方法經過形參指針(傳入函數的參數指針)來返回值。咱們要遵照這個命名習慣或者說規則。

在Objective-C 2.0中加入了@property和@synthesize來代替setter和getter,這兩個關鍵字爲編譯器指令。還有點表達式,存取類成員的值時,能夠使用點表達式。

Object.attribute,當點表達式在=號左邊時,調用的是setter方法,在=號右邊時,調用的是getter方法。

@property 語法爲:@property (參數) 類型 變量名.

在這裏主要說明一下參數.

參數分爲三種:

第一種:讀寫屬性包括(readonly/readwrite/)

第 二種:setter屬性(assign,copy,retain),assign是簡單的賦值,copy是釋放舊成員變量,並新分配內存地址給成 員 變量,將傳入參數內容複製一份,給成員變量。retain是將傳入   參數引用計數加1,而後將原有的成員變量釋放,在將成員變量指向該傳入參數。

第三種:與多線程有關(atomic,nonatomic).當使用多線程時,使用atomic,在不使用多線程時使用nonatomic

對象建立與初始化

在Objective-C中建立對象有兩種方法,一種是[類 new];另外一種是[[類 alloc] init],這兩種方法是等價的,但按慣例來說,使用[[類 alloc] init];

alloc操做是爲對象分配內存空間,並將對象的數據成員都初始,int 爲0,BOOL 爲NO, float 爲0.0等。

初始化,默認的初始化函數爲init,init返回值爲id,爲何回返回id呢,由於要實現鏈式表達式,在Objective-C中叫嵌套調用。

爲何要嵌套調用??由於初始化方法init返回值可能與alloc返回的對象不是同一個?爲何會發生這種狀況?基於類簇的初始化,由於init能夠接受參數,在init內部有可能根據不一樣的參數來返回不一樣種類型的對象,因此最會發生上面說的狀況。

在初始化時,建議使用if (self = [super init])

便利初始化

當一個類須要根據不一樣的狀況來初始化數據成員時,就須要便利初始化函數,與init初始化不一樣的是,便利初始化函數有參數,參數個數能夠有1到N個,N是類數據成員個數。

指定初始化函數:什麼是指定初始化函數?在類中,某個初始化函數會被指定爲指定的初始化函數,肯定指定初始化函數的規則是初始化函數中,參數最多的爲指定初始化函數,

其它未被指定爲指定初始化函數的初始化函數要調用指定初始化函數來實現。對於該類的子類也是同樣,只要重寫或者直接使用父類的指定初始化函數。上述文字有些繞,來個例子吧

@interface A{

int x;

int y;

}

-(id) init;

-(id) initWithX:(int) xValue;

-(id) initWithY:(int) yValue;

-(id) initWithXY:(int) xValue

yVal:(int) yValue;

@end

這裏initWithXY被肯定爲指定初始化函數。

-(id) initWithXY:(int) xValue

yVal:(int) yValue{

if (self = [super init]){

x = xValue;

y = yValue;

}

return self;

}

-(id) init{

if (self = self initWithXY:10

yVal:20){

}

return self;

}

.......

@interface B: A{

int z;

}

-(jd) initWithXY......;

@end

@implementation B

-(id) initWithXY:(int) xValue

yVal:(int) yValue{

if (self = [super initWithXY:10

yVal=20]){

z= 40;

}

return self;

}

@end

自動釋放池

內存管理是軟件代碼中的重中之重,內存管理的好壞,直接影響着軟件的穩定性。在Cocoa中,有自動釋放池,這相似於C++中的智能指針。

NSObject有一個方法是autorelease,當一個對象調用這個方法時,就會將這個對象放入到自動釋放池中。

drain,該方法是清空自動釋放池,不是銷燬它。drain方法只適用於Mac OS X 10.4以上的版本,在咱們寫的代碼中要使用release,release適用於全部版本。

自 動釋放池是以棧的方式實現,當建立一個自動釋放池A時,A被壓入棧頂,這時將接入autorelease消息的對象放入A自動釋放池,這時建立一 個新的 B自動釋放池,B被壓入棧頂,建立完成後刪除B,這個接收autorelease消息的對象依然存在,由於A自動釋放池依然存在。

引用計數

每一個對象都有一個與之相應的整數,稱它爲引用計數,當該引用計數爲0時,Objective-C自動向該對象發送dealloc,以銷燬該對向,與該引用計數相關的方法(消息)有下面幾個

1 增長引用計數:經過alloc,new,copy建立一個對象時,該對象的引用計數加1(其實就是1,由於以前爲0)

2 增長引用計數: retain

3 減小引用計數: release

局部分配內存(臨時對象):

1 若是使用alloc,new,copy建立對象,則須要主動調用對象的release方法

2 若是使用非alloc,new,copy建立對象,咱們認爲該對象引用計數爲1,並已經加入了自動釋放池,咱們不須要主動的調用對象的release方法。

擁有對象(在類中以成員的方法存在):

1 若是使用alloc,new,copy建立對象,則須要在dealloc方法中,釋放該對象

2 若是使用非alloc,new,copy建立對象,則在擁有該對象時,保留該對象(執行retain方法),在dealloc方法中,釋放該對象。

dealloc

當對象的引用計數爲0時,Objective-C會自動發送對象的dealloc消息(自動調用對象的dealloc方法,相似於C++的析構函數),因此咱們能夠本身重寫dealloc方法,來實現類裏的對其它使用資源的釋放工做。

注意:不要直接在代碼中顯示調用dealloc方法。

垃圾回收

在Objective-C 2.0中引入了垃圾回收機制(自動管理內存),在工程設置裏設置Objective-C Garbage Collection爲Required[-fobjc-gc-only]就能夠使用垃圾回收機制。

啓用垃圾回收機制後,一般的內存管理命令都變成了空操做指令,不執行任何操做。

Objective-C的垃圾回收機制是一種繼承性的垃圾回收器,垃圾回收器按期檢查變量和對象以及他們之間的指針,當發現沒有任何變量指向對象時,就將該對象視爲被丟棄的垃圾。因此在不在使用一個對象時,將指針他的指針設置爲nil,這時垃圾回收器就會清理該對象。

注意:若是開發iphone軟件,則不能使用垃圾回收。在編寫iPhone軟件時,Apple公司建議不要在本身的代碼中使用autorelease方法,而且不要使用建立自動釋放對象的函數。

類別

什麼是類別?類別是一種爲現有類添加新方法的方式。

爲何使用類別或者說使用類別的目的是什麼?有如下三點:

第一,能夠將類的實現分散到多個不一樣的文件或多個不一樣的框架中。

若是一個類須要實現不少個方法,咱們能夠將方法分類,把分好的類造成類別,能夠有效的管理和駕馭代碼。

第二,建立對私有方法的前向引用。

第三,向對象添加非正式協議。

委託

委託的意思就是你本身想作某事,你本身不作,你委託給別人作。

在Ojbective-C中,實現委託是經過類別(或非正式協議)或者協議來實現。

舉 個例子:Apple要生產iPhone,Apple本身不生產(種種緣由,其中之一就是在中國生產成本低,他們賺的銀子多),Apple委託富士 康來生 產,原本富士康原來不生產iPhone,如今要生產了,因此他得本身加一個生產iPhone的生產線(類別,增長生產iPhone方法),這就是經過類別 來實現委託。下面用代碼來講明這個例子。

.....

Apple *apple = [[Apple alloc ] init];

Foxconn *fox = [[Foxconn alloc] init];

[apple setDelegate:fox];

[apple produceIPhone];

........

@implementation Apple

-(...) setDelegate:(id) x{

delegate  = x; //! 將委託的生產對象指定爲x

}

-(...) produceIPhone{

[delegate produceIPhone]; //! 委託對象生產iPhone

}

@interface Foxconn : NSObject

...

@end

@interface NSObject(ProduceIPhone) //! Foxconn以前就能夠生產其它產品,有過聲明和定義

-(...) produceIPhone  //! 增長生產iPhone能力

@end

@implementation NSObject(ProduceIPhone)

//! 生產iPhone

-(...) produceIPhone{

......

}

@end

非正式協議

建立一個NSObject的類別, 稱爲建立一個非正式協議。爲何叫非正式協議呢?

也就是說能夠實現,也能夠不實現被委託的任務。

拿上面的例子來講,Apple要求Foxconn除了能生產iPhone外,還有一個要求是在必定時間內完成.因爲雙方沒有籤合同,因此時間要求和生產要求規格都是非正式協議

選擇器

選 擇器就是一個方法的名稱。選擇器是在Objective-C運行時使用的編碼方式,以實現快速查找。能夠使用@selector預編譯指令,獲取 選擇器 @selector(方法名)。NSObject提供了一個方法respondsToSelector:的方法,來訪問對象是否有該方法(響應該消息)。

拿 上面的Apple請Foxconn生產iPhone爲例,Apple怎麼知道Foxconn有沒有生產iPhone的能力呢?Apple就經過 respondsToSelector方法詢問Foxconn,是否能夠生產iPhone(是否能夠響應produceIPhone),詢問結果是能夠, 那Apple就委託Foxconn生產,Foxconn就生產出來了人們比較喜歡的iPhone產品。

正式協議

與非正式協議比較而言,在Ojbective-C中,正式協議規定的全部方法必須實現。在Ojbective-C2.0中,Apple又增長了兩個關鍵字,協議中的方法也能夠不徹底實現,是哪一個關鍵字見關鍵字部份的@optional,@required。

正式協議聲明以下:

@protocol XXX

-(...) func1;

-(...) func2;

@end

使用協議:

@interface Object : NSObject //! Object從NSObject派生,並遵循XXX協議,要實現func1,func2函數。

...

@end

習慣用法

分配內存和初始化

self = [super init];

對象間交互

在Objective-C中,全部對象間的交互都是經過指針實現。

快速枚舉

for (Type *p in array)

注意:

Objective-C不支持多繼承

objective-c只不過是擁有一些附加特性的C語言。本質上就是C語言

1.C語言使用#include通知編譯器應在頭文件中查詢定義。objective-c也能夠使用#include來實現這個目的,但你永遠不可能這麼作,你會用#import,它是GCC編譯器提供的,#import能夠保證頭文件只被包含一次。

xcode會使用預編譯頭文件(一種通過壓縮的,摘要形式的頭文件),在經過#import導入這種文件時,加載速度會很是快。

2.什麼是框架

框架是一種彙集在一個單元的部件集合,包含頭文件,庫,圖像,聲音文件等。蘋果公 司將cocoa,Carbon,QuickTime和OpenGL 等技術 做爲框架集提供。cocoa的組成部分有Foundation和Application Kit框架。還有一個支持框架的套件,包含 Core Animation和Core Image,這爲Cocoa增添了多種精彩的功能。

每一個框架都是一個重要的技術集合,一般包含數十個甚至上百個頭文件。每一個框架都有一個主頭文件,它包含了全部框架的各個頭文件。經過使用#import導入主頭文件,能夠使用全部框架的特性。

3.Foundation框架處理的是用戶界面之下的層(layer)中得特性,例如數據結構和通訊機制。

4.NS前綴

NS這個前綴告訴你函數來自cocoa而不是其餘工具包。

兩個不一樣事物使用相同標示符時會致使名稱衝突,而前綴能夠預防這個大問題。

5.BOOL類型

objective-c中得BOOL其實是一種對帶符號的字符類型(signed char)的定義。它使用8位存儲空間,YES爲1,NO爲0.

6.間接

不在代碼中直接使用某個值,而是使用指向該值的指針。另外一個意思是,讓別的類來完成本類的工做。

例子:

1.循環次數的變量。變量與間接

2.使用從文件讀取。文件與間接

在OOP(面向對象編程)中,間接十分重要。OOP使用間接來獲取數據,OOP真正的革命性就是它在調用代碼中使用間接。好比在調用函數時,不是直接調用,而是間接調用。

7.過程式程序與OOP的區別

過程式程序創建在函數之上,數據爲函數服務。面向對象編程從相反的角度來看待問題。它以程序的數據爲中心,函數爲數據服務。在OOP中,不在重點關注程序中得函數,而是專一與數據。

8.id

id是一種泛型,用於表示任何種類的對象。

9.OOP中得一些術語

類:類是一種結構,它表示對象的類型。對象引用類來獲取和自己有關的各類信息,特別是運行什麼代碼來處理每種操做。

對象:對象是一種結構,它包含值和指向其類的隱藏指針。

實例:實例是「對象」的另外一種稱呼。

消息:消息是對象能夠執行的操做,用於通知對象去作什麼。

方法:方法是爲響應消息而運行的代碼。根據對象的類,消息能夠調用不一樣的方法。

方法調度程序:是objective-c使用的一種機制,用於推測執行什麼方法以響應某個特定的消息。

接口:接口是對象的類應該提供的特性的描述。接口不提供實現細節。

實現:實現是使接口正常工做的代碼。

10.中綴符

objective- c有一種名爲中綴符的語法技術。方法的名稱及其參數都是合在一塊兒的。例如: [trxtThing setStringValue:@"Hello there" color:kBlueColor]; 中 setStringValue: 和 color:其實是參數的名稱(其實是方法名稱的一部分)。使代碼可讀性更強,更容易理解參數的用途。

11.先行短線

-(void)draw;

前面的短線代表這是objective-c方法的生命。這是一種區分函數原型與方法聲明的方式,函數原型中沒有先行短線。-表明是實例方法。+表明是類方法。

12.@interface

建立某個特定類的對象以前,objective-c編譯器須要一些有關該類的信息。他必須知道對象的數據成員和它提供的特性能夠使用@interface指令把這種信息傳遞給編譯器。用於定義類的公共接口。

13.@implementation

是一個編譯器指令,代表你將爲某個類提供代碼。類名出如今@implementation以後。該行的結尾處沒有分號。由於在objective-c編譯器指令後沒必要使用分號。

@interface和@implementation間的參數名不一樣是正確的。

在@interface中沒有聲明卻在@implementation中實現的方法是私有方法。

14.實例化

建立對象的過程叫作實例化。實例化對象時,須要分配內存,而後這些內存被初始化並保存一些有用的默認值,這些值不一樣於你在得到新分配內存時獲得的隨機值。內存分配和初始化完成後,就建立了一個新的對象實例。

15.繼承

建立一個新類時,一般須要定義新類以區別於其餘類以及現有類。使用繼承能夠定義一個具備父類全部功能的新類,它繼承了父類的這些功能。

objective-c沒有多繼承。

建立一個新類時,其對象首先從自身的超類中繼承實例變量,而後添加他們本身的實例變量。

超類

父類

子類

孩子類

重寫

方法調度:objective-c的方法調度程序將子當前類中搜索響應的方法。若是調度程序沒法在接受消息的對象類中找到響應的方法,它就會在該類的超類中進行查找。順着繼承鏈找到下一個超類進行查找,直到NSObject類中也沒有該方法,則會出現運行時錯誤。

16.複合

對象引用其餘對象時,能夠利用其餘對象提供的特性,這就是複合。

17.UML

UML是一種用圖表表示類,類的內容以及他們之間關係的常見方法。

18.多態

使用更具體種類的對象(子類對象)代替通常類型(父類),這種能力稱爲多態性。

19.self

是一個指向接收消息的對象的指針。指向第一個實例變量isa。由於objective-c編譯器已經看到了全部這些類的@interface聲明,所以,它能直到對象中實力變量的佈局,經過這些重要的信息,編譯器能夠產生代碼並查找任何須要的實例變量。

基地址加偏移:編譯器使用「基地址加偏移」機制實現奇妙的功能。給定的對象基地址,是指第一個實例變量的首個字節在內存中得位置,經過在該地址加上偏移地址,編譯器就能夠查到其餘實例變量的位置。

20.間接尋址方式,直接尋址方式

21.super

objective-c提供某種方式來重寫方法,而且仍然調用超類的實現方式。當須要超類實現自身的功能,同時在前面或者後面執行某些額外的工做時,這種機制很是有用。爲了調用繼承方法的實現,須要使用super做爲方法調用的目標。

22.cocoa

cocoa其實是由2個不一樣的框架組成的:Foundation Kit和 Application Kit。Application Kit包含了全部的用戶接口對象和高級類。

Foundation Kit

23.NSAutoreleasePool

mian()函數建立了(經過alloc)並初始化(經過init)了一個NSAutoreleasePool實例。在mian()函數結尾,這個池被排空。這就是Cocoa內存管理的預覽。

24.NSRange

typedef struct _NSRange {

unsigned int location;

unsigned int length;

}NSRange;

這個結構體用來表示相關事務的範圍,一般是字符串裏的字符範圍或者數組裏的元素範圍。

25.三種賦值方式

1.NSRange range;

range.location = 17;

range.length = 4;

2.C語言的聚合結構賦值機制

NSRange range = {17, 4};

3.Cocoa提供的一個快捷函數NSMakeRange()

NSRange range = NSMakeRange(17, 4);

使用NSMakeRange()的好處是你能夠在任何可以使用函數的地方使用它,例如在方法調用中將其當成參數傳遞。

26.幾何數據類型

1.NSPoint  表明笛卡兒平面中得一個點(x, y).

typedef struct _NSPoint {

float x;

float y;

}NSPoint;

2.NSSize  用來存儲長度和寬度

typedef struct NSSize {

float width;

float height;

}NSSize;

3.NSRect 矩形數據類型,它是由點和大小複合而成

typedef struct _NSRect {

NSPoint origin;

NSSize size;

}NSRect;

27.字符串NSString

stringWithFormat:就是一個工廠方法,它根據你提供的參數建立新對象。

length:長度

isEqualToString:比較字符串內容是否相同

compart:將接受對象和傳遞來的字符串逐個字符的進行比較。返回一個enum數據

NSCaseInsensitiveSearch:不區分大小寫字符。

NSLiteralSearch:進行徹底比較,區分大小寫

NSNumericSearch:比較字符串的字符個數,而不是字符值。

-(NSRange)rangeOfString:(NSString *)aString;

返回的range.start爲開始位置,range.length爲長度。

28.NSMutableString可變字符串。

stringWithCapacity:建立一個新的NSMutableString

字符串的大小並不只限於所提供的容量,這個容量僅是個最優值。若是要建立一個40mb的字符串。

NSMutableString *str = [NSMutableString stringWithCapacity:42];

appendString接受參數aString,而後將其複製到接收對象的末尾。

appendFormat與stringWithFormat:相似,但它將格式化的字符串附加在接收字符串的末尾,而不是建立新的字符串對象。

29.集合家族

1.NSArray:是一個Cocoa類,用來存儲對象的有序列表。

兩個限制:1.只能存儲objective-c的對象,不能存儲C語言中得基本數據類型。

2.也不能存儲nil。

30.枚舉器,快速枚舉

31.NSDictionary字典

關鍵字及其定義的集合。

32.NSNumber包裝(以對象形式實現)基本數據類型

裝箱:將一個基本類型的數據包裝成對象。

取消裝箱:從對象中提取基本類型的數據。

objective-c不支持自動裝箱。

33.NSValue是NSNumber的父類。

+(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;

傳 遞的參數是你想要包裝的數值的地址(如一個NSSize或你本身的struct)。一般,獲得的是你想要存儲的變量的地址(在C語言中使用操做 符&)。你也能夠提供一個用來描述這個數據類型的字符串,一般用來講明struct中實體的類型和大小。你不用本身寫代碼來生成這個字符 串,@encode編譯器指令能夠接受數據類型的名稱併爲你生成合適的字符串。

NSRect rect = NSMakeRect(1, 2, 30, 40);

NSValue *value;

value = [NSValue valueWithBytes:&rect objCType:@encode(NSRect)];

[array addObject:value];

34.NSNull只有一個方法[NSNull null];

[NSNull null]老是返回同樣的數值,因此你能夠使用運算符==將該值與其餘值進行比較。

35.單實例架構:只須要一個實例。

查找文件:

例如:NSFileManager *manager;

manager = [NSFileManager defaultManager];

defaultManager能夠爲咱們建立一個屬於咱們本身的NSFileManger對象。

NSString *home = [@"~" stringByExpandingTildeInPath];將~替換成當前用戶的主目錄。

NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:home]; 返回一個 NSDictionaryEnumerator,它是NSEnumerator的子類。每次在這個枚舉器對象中調用nextObject時,都會返回該目 錄中得一個文件的另外一個路徑。

36.內存管理

1)對象生命週期

對象的生命週期包括誕生(alloc或者new方法實現),生存(接受消息和執行操做),交友(藉助方法的組合和參數)以及當他們的生命結束時最終死去(被釋放)。當對象的生命週期結束時,他們的原材料(內存)將被回收以供新的對象使用。

2)引用計數

cocoa 採用了一種稱爲引用計數的技術,有時候也叫保留計數。每一個對象有一個與之相關聯的整數,稱做它的引用計數器或保留計數器。當某段代碼須要 訪問一 個對象時,該代碼將該對象的保留計數器值+1,表示「我要訪問該對象」。當這段代碼結束對象訪問時,將對象的保留計數器值-1,表示它再也不訪問該對象,當 保留計數器值爲0時,表示再也不有代碼訪問該對象了,所以該對象被銷燬,其佔用的內存被系統回收以便重用。

alloc,new,copy  1

retain  +1

release  -1

3)對象全部權

若是一個對象具備指向其餘對象的實力變量,則稱該對象擁有這些對象。

在類A中  B對象擁有其指向的C對象,則B對象擁有C對象。

若是一個函數建立了一個對象,則稱該函數擁有它建立的這個對象。

main()函數建立了對象a  稱main()函數擁有a對象

當多個實體擁有某個特定的對象時,對象的全部權關係就更加複雜了,這也是保留計數器值可能大於1的緣由。

例子:

main() {

Engine *engine = [Engine new];

[car setEngine:engine];

}

現 在哪一個實體擁有engine對象?是main函數仍是car類?哪一個實體負責確保當engine對象再也不被使用時可以收到release消息?因 爲 car類正在使用engine對象,因此不多是main函數。由於main函數隨後還可能會使用engine對象,因此也不多是car類。

解 決方法是讓car類保留engine對象,將engine對象的保留計數器值增長到2。這是由於car類和main函數這2個實體都正在使用 engine對象。car類應該在setEngine:方法中保留engine對象,而main函數應該釋放engine對象。而後,當car類完成其任 務時再釋放engine對象(在其dealloc方法中),最後engine對象佔用的資源被回收。

若是您使用名字以「alloc」或 「new」開頭或名字中包含「copy」的方法(例如alloc,newObject或mutableCopy) 建立了 一個對象,則您會得到該對象的全部權;或者若是您向一個對象發送了一條retain消息,則您也會得到該對象的全部權。

4)訪問方法中得保留和釋放

5)自動釋放池NSAutoreleasePool

是一個存放實體的池(集合)。你能夠用NSMutableArray來編寫本身的自動釋放池,以容納對象並在dealloc方法中向池中得全部對象發送release消息。

autorelease

當給一個對象發送autorelease消息時,其實是將該對象添加到NSAutoreleasePool中。當自動釋放池被銷燬時,會向該池中得全部對象發送release消息。

6)自動釋放池的銷燬時間

在咱們一直使用的Foudation庫工具中,建立和銷燬自動釋放池的方法很是明確:

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

...

[pool release];

創 建一個自動釋放池時,該池自動成爲活動的池。釋放該池時,其保留計數器值歸0,而後該池被銷燬。在銷燬的過程當中,該池釋放其包含的全部對象。當使 用 Application Kit時,cocoa按期自動爲你建立和銷燬自動釋放池。一般是在程序處理完當前事件之後執行這些操做。你能夠使用任意多得自動 釋放對象,當再也不使用它們時,自動釋放池將自動爲你清理這些對象。

你可能已經在xcode自動生成代碼中碰見過另外一種銷燬自動釋放池中對象的方式:-drain方法。該方法只是清空自動釋放池而不是銷燬它。而且只適用於mac os x10.4以上的版本。

7)自動釋放池的工做過程

我 們在任什麼時候候向一個對象發送autorelease消息,該對象都會唄添加到這個自動釋放池中。被加入到自動釋放池的對象的引用計數器值不會變 化。當自 動釋放池被銷燬時(向自動釋放池發送release消息,自動釋放池的引用計數器值變爲0,調用自身的dealloc函數),會調用自身的dealloc 函數,會向池中得對象發送release消息。

37.cocoa內存管理規則

1)當你使用new,alloc或copy方法建立一個對象時,該對象的保留計數器值爲1。當再也不使用該對象時,你要負責向該對象發送一條release或autorelease消息。這樣,該對象將在其使用壽命結束時被銷燬。

2)當你經過任何其餘方法得到一個對象時,則假設該對象的保留計數器值爲1,並且已經被設置爲自動釋放,你不須要執行任何操做來確保該對象被清理。若是你打算在一段時間內擁有該對象,則須要保留它並確保在操做完成時釋放它。

3)若是你保留了某個對象,你須要(最終)釋放或自動釋放該對象。必須保持retain方法和release方法的使用次數相同。

38.清理自動釋放池

因爲自動釋放池的銷燬時間是徹底確立的,因此它在循環執行過程當中不會被銷燬。在迭代中或者循環中,須要創建本身的自動釋放池。

39.垃圾回收gc

自 動內存管理機制。objective-c的垃圾回收器是一種繼承性的垃圾回收器。與那些已經存在了一段時間的對象相比,新建立的對象更可能被當成 垃圾。 垃圾回收器按期檢查變量和對象以及他們之間的指針,當發現沒有任何變量指向某個對象時,就將該對象視爲應該被丟棄的垃圾。若是你再一個實例變量中指向某個 對象,必定要在某個時候使該實例變量賦值爲nil,以取消對該對象的引用並使垃圾回收器知道該對象能夠被清理了。

與自動釋放池同樣,垃圾回收器也是在時間循環結束時才觸發。

ARC是什麼?

ARC是iOS 5推出的新功能,全稱叫 ARC(Automatic Reference Counting)。簡單地說,就是代碼中自動加入了retain/release,原先須要手動添加的用來處理內存管理的引用計數的代碼能夠自動地由編譯器完成了。

該 機能在 iOS 5/ Mac OS X 10.7 開始導入,利用 Xcode4.2 能夠使用該機能。簡單地理解ARC,就是經過指定的語 法,讓編 譯器(LLVM 3.0)在編譯代碼時,自動生成實例的引用計數管理部分代碼。有一點,ARC並非GC,它只是一種代碼靜態分析 (Static Analyzer)工具。

40.分配

是一個新對象誕生的過程。是從操做系統得到一塊內存並將其指定爲存放對象的實例變量的位置。

40.初始化

與分配對應的操做是初始化。初始化從操做系統取得一塊內存。準備用於存儲對象。

嵌套調用技術很是重要,由於初始化方法返回的對象可能與分配的對象不一樣。

1)初始化時作什麼?

給實例變量賦值並建立你得對象完成任務所須要的其餘對象。

2)便利初始化函數

許多類包含便利初始化函數。用來完成某些額外的工做的初始化方法,能夠減小你本身完成這些工做的麻煩。

例如:NSString類中-(id)initWithFormat:(NSString *)format,...;

3)指定初始化函數

類中的某個初始化方法被指派爲指定初始化函數。該類全部初始化方法使用指定初始化函數執行初始化操做。子類使用其超類的指定初始化函數實現超類的初始化。

例如:其餘初始化函數經過指定初始化函數實現。

41.初始化函數規則

不須要爲你本身的類建立初始化函數方法。若是不須要設置任何狀態,或者只須要alloc方法將內存清零的默認行爲,則不須要擔憂init。

若是構造了一個初始化函數,則必定要在你本身的指定初始化函數中調用超類的指定初始化函數。必定要將超類的初始化函數的值賦給self對象,並返回你本身的初始化方法的值。由於超類可能決定返回一個徹底不一樣的對象。

若是初始化函數不止一個,則要選擇一個座位指定初始化函數。被選定的方法應該調用超類指定初始化函數。要按照指定初始化函數的形式實現全部其餘初始化函數,就像咱們在前面的實現同樣。

42.特性@property

objective-c2.0的特性只適用於mac os x 10.5或更高版本。特性主要應用於cocoa的新組件(尤爲是華麗奪目的core Animation效果)。

1)簡化接口

@property預編譯指令的做用是自動生命屬性的setter和getter方法。

2)@synthesize也是一種新的編譯器功能,表示「建立該屬性的訪問器」。

3)點表達式

若是點表達式出如今=左邊,該屬性名稱的setter方法(set方法)將被調用。若是點表達式出如今對象變量右邊,則該屬性名稱的getter方法(get方法)將被調用。

4)特性擴展

@property()括號裏面的東西,是對應在set方法中要添加的語句。好比我在括號裏寫retain,就至關於在它的set方法裏添加了一句 [xx retain]。

@property屬性

屬性分爲3類:

1.讀寫屬性(Writability)包含:readwrite / readonly

2.setter語義(Setter Semantics)包含:assign / retain / copy

3.原子性(Atomicity)包含:nonatomic

下面具體說明各個屬性的含義

readwrite / readonly:

決定是否生成set訪問器,readwrite是默認屬性,生成getter和setter方法;readonly只生成getter方法,不生成setter方法。

readonly關鍵字表明setter不會被生成, 因此它不能夠和 copy/retain/assign組合使用。

assign / retain / copy:

這些屬性用於指定set訪問器的語義,也就是說,這些屬性決定了以何種方式對數據成員賦予新值。

assign:

直接賦值,索引計數不改變,適用於簡單數據類型,例如:NSIngeter、CGFloat、int、char等。

retain:

指針的拷貝,使用的是原來的內存空間。

對象的索引計數加1。

此屬性只能用於Objective-C對象類型,而不能用於Core Foundation對象。(緣由很明顯,retain會增長對象的引用計數,而基本數據類型或者Core Foundation對象都沒有引用計數)。

copy:

對象的拷貝,新申請一塊內存空間,並把原始內容複製到那片空間。

新對象的索引計數爲1。

此屬性只對那些實行了NSCopying協議的對象類型有效。

不少Objective-C中的object最好使用用retain,一些特別的object(例如:string)使用copy。

nonatomic:

非原子性訪問,不加同步,多線程併發訪問會提升性能。若是不加此屬性,則默認是兩個訪問方法都爲原子型事務訪問。默認值是atomic,爲原子操做。

(atomic是Objc使用的一種線程保護技術,基本上來說,是防止在寫未完成的時候被另一個線程讀取,形成數據錯誤。而這種機制是耗費系統資源的, 因此在iPhone這種小型設備上,若是沒有使用多線程間的通信編程,那麼nonatomic是一個很是好的選擇。)

5)保留週期retain cycle

引用計數器在該週期中歸零。

6)什麼是屬性訪問器

屬性訪問器(Property Accessor),包括 get 訪問器和 set 訪問器分別用於字段的讀寫操做

其設計目的主要是爲了實現面向對象(OO)中的封裝思想。根據該思想,字段最好設爲private,一個精巧的類最好不要直接把字段設爲公有提供給客戶調用端直接訪問

另外要注意屬性自己並不必定和字段相聯繫

7)self.a與a的區別

self.a使編譯器知道咱們指望使用訪問器訪問a。若是隻使用裸名a,編譯器將假設咱們直接修改了實例變量。

8)self.a = nil

這 行代碼表示使用nil參數調用setName:方法。生成的訪問器方法將自動釋放之前的name對象,並使用nil替代a。該方法完成了釋放 name對 象所佔用內存的操做。固然,也能夠只釋放name對象以清理其佔用的內存。若是你再dealloc方法之外的地方清除特性,那麼使用"將nil賦值給對 象"的方法能夠將特性設置爲nil,同時能夠使咱們避免對已釋放內存的懸空引用問題。

9)特性不是萬能的

有些方法不適合特性所能涵蓋的方法的至關狹小的範圍。特性不支持那些須要接受額外參數的方法。

43.類別@category

1)聲明類別

@interface NSString (NumberConvenience)

-(NSNumber *)lengthAsNumber;

@end

該 聲明具備2個特色。首先,現有類位於@interface關鍵字以後,其後是位於圓括號中的一個新名稱。該聲明表示,類別的名稱是 NumberConvenience,並且該類別將向NSString類中添加方法。只要保證類別名稱的惟一性,你能夠向一個類中添加任意多得類別。

其次,你能夠指定但願向其添加類別的類以及類別的名稱,並且你還能夠列出添加的方法,最後以@end結束。因爲不能添加新實現變量,所以與類聲明不一樣的是,類別的聲明中沒有實例變量部分。

2)實現類別

3)類別的侷限性

第一,沒法向類中添加新的實例變量。類別沒有位置容納實例變量。

第二,名稱衝突,即類別中得方法與現有的方法重名。當發生名稱衝突時,類別具備更高的優先級。你得類別方法將徹底取代初始方法,從而沒法再使用初始方法。有些編程人員在本身的類別方法中增長一個前綴,以確保不發生名稱衝突。

有一些技術能夠克服類別沒法增長新實例變量的侷限。例如,能夠使用全局字典存儲對象與你想要關聯的額外變量之間的映射。但此時你可能須要認真考慮一下,類別是不是完成當前任務的最佳選擇。

4)類別的做用

cocoa中得類別主要用於3個目的:第一,將類的實現分散到不一樣文件或者不一樣框架中。第二,建立對私有方法的前向引用。第三,向對象添加非正式協議。

44.run循環是一種cocoa構造,它一直處於阻塞狀態(即不執行任何處理),知道某些事件發生爲止。

45.響應選擇器

一個類別如何知道其委託對象是否可以處理那些發送給它的消息?

類別首先檢查對象,詢問其可否響應該選擇器。若是該對象可以響應該選擇器,

1)選擇器@selector()

選擇器只是一個方法名稱,但它以objective-c運行時使用的特殊方式編碼,以快速執行查詢。你能夠使用@selector()預編譯指令選擇器,其中方法名位於圓括號中。

46.委託  非正式協議

47.正式協議

與非正式協議同樣,正式協議是一個命名的方法列表。但與非正式協議不一樣的是,正式協議要求顯式的採用協議。採用協議的辦法是在類的@interface聲明中列出協議名稱。採用協議意味着你承諾實現該協議的全部方法。

1)聲明協議

@protocol NSCopying

-(id)copyWithZone:(NSZone *)zone;

@end

2)採用協議

@interface Car: NSObject 

{

}

@end

3)協議和數據類型

若是一個用尖括號括起來的協議名稱跟隨在id以後,則編譯器將知道你指望任意類型的對象,只要其遵照該協議。

4)objective-c2.0的新特性@optional @required

@optional可選擇實現的方法

@required必須實現的方法

所以cocoa中得非正式協議正被帶有@optional的正式協議所取代。

48.Application Kit

1)IBOutlet與IBAction

他 們實際上只是APPKit提供的#defines。IBOutlet的定義沒有任何做用,所以將不會對它進行編譯。IBAction定義爲 void,這 意味着在AppController中聲明的方法的返回類型將使void。IBOutlet和IBAction不執行任何操做,他們並非用於編譯的,實 際上他們是爲Interface Builder以及閱讀代碼的人提供的標記。經過查找IBOutlet和 IBAction,Interface Builder知道AppController對象具備兩個可以鏈接的實例變量。

2)IBOutlet是如何工做的

當 加載nib文件時(MainMenu.nib會在應用程序啓動時自動加載,能夠建立你本身的nib文件並自行加載),存儲在nib文件中得任何對 象都會 被從新建立。這意味着會再後臺執行alloc和init方法。因此,當應用程序啓動時,會分配並初始化一個AppController實例。在執行 init方法期間,全部IBOutlet實例變量都爲nil。只有建立了nib文件中得全部對象(這包括窗口和文本域和按鈕),全部鏈接纔算完成。

一 旦創建了全部鏈接(也就是將NSTextField對象的地址添加到AppController的實例變量中),會向建立的每一個對象發送消息 awakeFromNib。一個很是常見的錯誤是試圖在init方法中使用IBOutlet執行一些操做。因爲全部實例變量都爲nil,發送給他們的全部 消息不執行任何操做,因此在init中得任未嘗試都會發生無提示失敗。(這是Cocoa致使效率低和佔用大量調試時間的一個方面)。若是你想知道爲何這 些操做不起做用,能夠使用NSLog輸出實例變量的值,並查看他們是否都爲nil。對於建立的對象和發送的awakeFromNib消息,都不存在預約義 順序。

文件加載與保存

49.屬性列表

1)自動釋放對象

NSDate

NSData NSData對象是不可改變的。他們被建立後就不能改變。能夠使用他們,但不能改變其中的內容。

2)編碼對象    編碼和解碼

cocoa具有一種機制來將對象自身轉換爲某種格式並保存到磁盤中。對象能夠將他們的實例變量和其餘數據塊編碼爲數據塊,而後保存到磁盤中。之後將這些數據塊讀回到內存中,而且還能基於保存的數據建立新對象。這個過程稱爲編碼和解碼。或稱爲序列化和反序列化。

50.鍵/值編碼   KVC

是一種間接改變對象狀態的方式,其實現方法是使用字符串描述要更改的對象狀態部分。

1)valueForKey與setValue:forKey:

這兩種方法的工做方式相同。他們首先查找名稱的setter(getter)方法,若是不存在setter(getter)方法,他們將在類中查找名爲名稱或_名稱的實例變量。而後給它賦值(取值)。無需經過對象指針直接訪問實例變量。

2)路徑

鍵路徑的深度是任意的,具體取決於對象圖。

鍵路徑不只能引用對象值,還能夠引用一些運算符來進行一些運算,例如獲取一組值的平均值或返回這組值中得最小值和最大值。

例如:NSNumber *count;

count = [garage valueForKeyPath:@"cars.@count"];

NSLog(@"We have %@ cars", count);

咱們將路徑「cars.@count」拆開,cars用於獲取cars屬性,它是來自garage的NSArray類型的值。接下來的部分是@count ,其中@符號意味着後面將進行一些運算。

和 cars@sun.mileage

最大值 cars@min.mileage

最小值 cars@max.mileage

3)總體操做

KVC很是棒的一點是,若是向NSArray請求一個鍵值,它實際上會查詢數組中得每一個對象來查找這個鍵值,而後將查詢結果打包到另外一個數組中並返回給你。這種方法也適用於經過鍵路徑訪問的對象內部的數組。

4)批處理

KVC包含兩個調用,能夠使用他們對對象進行批量更改。第一個調用是dictionaryWith-ValuesForKeys:。它接受一個字符串數組。該調用獲取一些鍵,對每一個鍵使用valueForKey:,而後爲鍵字符串和剛纔獲取的值構建一個字典。

一、Object-C有多繼承嗎?沒有的話用什麼代替?cocoa 中全部的類都是NSObject 的子類

多繼承在這裏是用protocol 委託代理 來實現的

你不用去考慮繁瑣的多繼承 ,虛基類的概念.

ood的多態特性 在 obj-c 中經過委託來實現.

二、Object-C有私有方法嗎?私有變量呢?

objective-c – 類裏面的方法只有兩種, 靜態方法和實例方法. 這彷佛就不是完整的面向對象了,按照OO的原則就是一個對象只暴露有用的東西. 若是沒有了私有方法的話, 對於一些小範圍的代碼重用就不那麼順手了. 在類裏面聲名一個私有方法

@interface Controller : NSObject { NSString *something; }

+ (void)thisIsAStaticMethod;

– (void)thisIsAnInstanceMethod;

@end

@interface Controller (private) -

(void)thisIsAPrivateMethod;

@end

@private能夠用來修飾私有變量

在Objective‐C中,全部實例變量默認都是私有的,全部實例方法默認都是公有的

三、關鍵字const什麼含義?

const意味着」只讀」,下面的聲明都是什麼意思?

const int a;

int const a;

const int *a;

int * const a;

int const * a const;

前 兩個的做用是同樣,a是一個常整型數。第三個意味着a是一個指向常整型數的指針(也就是,整型數是不可修改的,但指針能夠)。第四個意思a是一個 指向整 型數的常指針(也就是說,指針指向的整型數是能夠修改的,但指針是不可修改的)。最後一個意味着a是一個指向常整型數的常指針(也就是說,指針指向的整型 數是不可修改的,同時指針也是不可修改的)。

結論:

?; 關鍵字const的做用是爲給讀你代碼的人傳達很是有用的信息, 實際上,聲明一個參數爲常量是爲了告訴了用戶這個參數的應用目的。若是你曾花 不少時間清理其它人留下的垃圾,你就會很快學會感謝這點多餘的信息。(固然,懂得用const的程序員不多會留下的垃圾讓別人來清理的。)

?; 經過給優化器一些附加的信息,使用關鍵字const也許能產生更緊湊的代碼。

?; 合理地使用關鍵字const能夠使編譯器很天然地保護那些不但願被改變的參數,防止其被無心的代碼修改。簡而言之,這樣能夠減小bug的出現。

欲阻止一個變量被改變,能夠使用 const 關鍵字。在定義該 const 變量時,一般須要對它進行初

始化,由於之後就沒有機會再去改變它了;

(2)對指針來講,能夠指定指針自己爲 const,也能夠指定指針所指的數據爲 const,或兩者同時指定爲 const;

(3)在一個函數聲明中,const 能夠修飾形參,代表它是一個輸入參數,在函數內部不能改變其值;

(4)對於類的成員函數,若指定其爲 const 類型,則代表其是一個常函數,不能修改類的成員變量;

(5)對於類的成員函數,有時候必須指定其返回值爲 const 類型,以使得其返回值不爲「左值」。

四、關鍵字volatile有什麼含義?並給出三個不一樣例子?

一個定義爲volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到

這個變量時必須每次都當心地從新讀取這個變量的值,而不是使用保存在寄存器裏的備份。下面是volatile變量的幾個例子:

並行設備的硬件寄存器(如:狀態寄存器)

一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)

多線程應用中被幾個任務共享的變量

一個參數既能夠是const還能夠是volatile嗎?解釋爲何。

一個指針能夠是volatile 嗎?解釋爲何。

下面是答案:

是的。一個例子是隻讀的狀態寄存器。它是volatile由於它可能被意想不到地改變。它是const由於程序不該該試圖去修改它。

是的。儘管這並不很常見。一個例子是當一箇中服務子程序修該一個指向一個buffer的指針時。

static做用?

函數體內 static 變量的做用範圍爲該函數體,不一樣於 auto 變量,該變量的內存只被分配一次,

所以其值在下次調用時仍維持上次的值;

(2)在模塊內的 static 全局變量能夠被模塊內所用函數訪問,但不能被模塊外其它函數訪問;

(3)在模塊內的 static 函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明

它的模塊內;

(4)在類中的 static 成員變量屬於整個類所擁有,對類的全部對象只有一份拷貝;

(5)在類中的 static 成員函數屬於整個類所擁有,這個函數不接收 this 指針,於是只能訪問類的static 成員變量。

六、#import和#include的區別,@class表明什麼?

@class通常用於頭文件中須要聲明該類的某個實例變量的時候用到,在m文件中仍是須要使用#import

而#import比起#include的好處就是不會引發重複包含

七、線程和進程的區別?

進程和線程都是由操做系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。

進 程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程 只是一 個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程 序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。

八、堆和棧的區別?

管理方式:對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來講,釋放工做由程序員控制,容易產生memory leak。

申請大小:

棧: 在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就肯定的常數),若是申請的空間超過棧的剩餘空間時,將提示overflow。因 此,能從棧得到的空間較小。

堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是因爲系統是用鏈表來存儲的空閒內存地址的,天然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。

碎片問題:對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降。對於棧來說,則不會存在這個問題,由於棧是先進後出的隊列,他們是如此的一一對應,以致於永遠都不可能有一個內存塊從棧中間彈出

分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,好比局部變量的分配。動態分配由alloca函數進行分配,可是棧的動態分配和堆是不一樣的,他的動態分配是由編譯器進行釋放,無需咱們手工實現。

分配效率:棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的。

九、Object-C的內存管理?

1.當你使用new,alloc和copy方法建立一個對象時,該對象的保留計數器值爲1.當你再也不使用該對象時,你要負責向該對象發送一條release或autorelease消息.這樣,該對象將在使用壽命結束時被銷燬.

2.當你經過任何其餘方法得到一個對象時,則假設該對象的保留計數器值爲1,並且已經被設置爲自動釋放,你不須要執行任何操做來確保該對象被清理.若是你打算在一段時間內擁有該對象,則須要保留它並確保在操做完成時釋放它.

3.若是你保留了某個對象,你須要(最終)釋放或自動釋放該對象.必須保持retain方法和release方法的使用次數相等.

十、爲何不少內置的類,如TableViewController的delegate的屬性是assign不是retain?

循環引用

全部的引用計數系統,都存在循環應用的問題。例以下面的引用關係:

對象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兩端產生沒必要要的循環引用。若是一個UITableViewController 對象a通 過retain獲取了UITableView對象b的全部權,這個UITableView對象b的delegate又是a,若是這個delegate是 retain方式的,那基本上就沒有機會釋放這兩個對象了。本身在設計使用delegate模式時,也要注意這點。

十一、定義屬性時,什麼狀況使用copy、assign、retain?

assign用於簡單數據類型,如NSInteger,double,bool,

retain和copy用於對象,

copy用於當a指向一個對象,b也想指向一樣的對象的時候,若是用assign,a若是釋放,再調用b會crash,若是用copy 的方式,a和b各自有本身的內存,就能夠解決這個問題。

retain 會使計數器加一,也能夠解決assign的問題。

另外:atomic和nonatomic用來決定編譯器生成的getter和setter是否爲原子操做。在多線程環境下,原子操做是必要的,不然有可能引發錯誤的結果。

加了atomic,setter函數會變成下面這樣:

if (property != newValue) {

[property release];

property = [newValue retain];

}

十二、對象是何時被release的?

引用計數爲0時。

autorelease 實際上只是把對release的調用延遲了,對於每個Autorelease,系統只是把該Object放入了當前的 Autorelease pool中,當該pool被釋放時,該pool中的全部Object會被調用Release。對於每個Runloop,系統會 隱式建立一個Autorelease pool,這樣全部的release pool會構成一個象CallStack同樣的一個棧式結構,在每個 Runloop結束時,當前棧頂的Autorelease pool會被銷燬,這樣這個pool裏的每一個Object(就是autorelease的對 象)會被release。那什麼是一個Runloop呢?一個UI事件,Timer call, delegate call, 都會是一個新的 Runloop

1三、iOS有沒有垃圾回收?

Objective-C 2.0也是有垃圾回收機制的,可是隻能在Mac OS X Leopard 10.5 以上的版本使用。

1四、tableView的重用機制?

查 看UITableView頭文件,會找到NSMutableArray*  visiableCells,和 NSMutableDictnery* reusableTableCells兩個結構。visiableCells內保存當前顯示的 cells,reusableTableCells保存可重用的cells。

TableView顯示之 初,reusableTableCells爲空,那麼 tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。開始的cell都 是經過 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 來建立,並且cellForRowAtIndexPath只是調用最大顯示cell數的次數。

好比:有100條數據,iPhone一屏最多顯示10個cell。程序最開始顯示TableView的狀況是:

1. 用 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 建立10次cell,並給cell指定一樣的重用標識(固然,能夠爲不一樣顯示類型的cell指定不一樣的標識)。而且10個cell所有都加入到 visiableCells數組,reusableTableCells爲空。

2.向下拖動tableView,當cell1徹底移出屏 幕,而且cell11(它也是alloc出來的,緣由同上)徹底顯示出來的時候。 cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。

3. 接着向下拖動tableView,由於reusableTableCells中已經有值,因此,當須要顯示新的 cell,cellForRowAtIndexPath再次被調用的時 候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。 cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells。以後再須要顯示的Cell就能夠正常重用了。

1五、ViewController 的loadView、viewDidLoad、viewDidUnload分別是何時調用的,在自定義ViewCointroller時在這幾個函數中應該作什麼工做?

由init、loadView、viewDidLoad、viewDidUnload、dealloc的關係提及

init方法

在init方法中實例化必要的對象(聽從LazyLoad思想)

init方法中初始化ViewController自己

loadView方法

當view須要被展現而它倒是nil時,viewController會調用該方法。不要直接調用該方法。

若是手工維護views,必須重載重寫該方法

若是使用IB維護views,必須不能重載重寫該方法

loadView和IB構建view

你 在控制器中實現了loadView方法,那麼你可能會在應用運行的某個時候被內存管理控制調用。 若是設備內存不足的時候, view 控制器會 收到 didReceiveMemoryWarning的消息。 默認的實現是檢查當前控制器的view是否在使用。若是它的view不在當前正在使用的 view hierarchy裏面,且你的控制器實現了loadView方法,那麼這個view將被release, loadView方法將被再次調用 來建立一個新的view。

viewDidLoad方法

viewDidLoad 此方法只有當view從nib文件初始化的時候才被調用。

重載重寫該方法以進一步定製view

在iPhone OS 3.0及以後的版本中,還應該重載重寫viewDidUnload來釋放對view的任何索引

viewDidLoad後調用數據Model

viewDidUnload方法

當系統內存吃緊的時候會調用該方法(注:viewController沒有被dealloc)

內存吃緊時,在iPhone OS 3.0以前didReceiveMemoryWarning是釋放無用內存的惟一方式,可是OS 3.0及之後viewDidUnload方法是更好的方式

在該方法中將全部IBOutlet(不管是property仍是實例變量)置爲nil(系統release view時已經將其release掉了)

在 該方法中釋放其餘與view有關的對象、其餘在運行時建立(但非系統必須)的對象、在viewDidLoad中被建立的對象、緩存數據 等 release對象後,將對象置爲nil(IBOutlet只須要將其置爲nil,系統release view時已經將其release掉了)

通常認爲viewDidUnload是viewDidLoad的鏡像,由於當view被從新請求時,viewDidLoad還會從新被執行

viewDidUnload中被release的對象必須是很容易被從新建立的對象(好比在viewDidLoad或其餘方法中建立的對象),不要release用戶數據或其餘很難被從新建立的對象

dealloc方法

viewDidUnload和dealloc方法沒有關聯,dealloc仍是繼續作它該作的事情

1六、ViewController的didReceiveMemoryWarning是在何時調用的?默認的操做是什麼?

當程序接到內存警告時View Controller將會收到這個消息:didReceiveMemoryWarning

從iOS3.0開始,不須要重載這個函數,把釋放內存的代碼放到viewDidUnload中去。

這個函數的默認實現是:檢查controller是否能夠安全地釋放它的view(這裏加粗的view指的是controller的view屬性),好比view自己沒有superview而且能夠被很容易地重建(從nib或者loadView函數)。

若是view能夠被釋放,那麼這個函數釋放view並調用viewDidUnload。

你能夠重載這個函數來釋放controller中使用的其餘內存。但要記得調用這個函數的super實現來容許父類(通常是UIVIewController)釋放view。

若是你的ViewController保存着view的子view的引用,那麼,在早期的iOS版本中,你應該在這個函數中來釋放這些引用。而在iOS3.0或更高版本中,你應該在viewDidUnload中釋放這些引用。

1七、列舉Cocoa中常見的集中多線程的實現,並談談多線程安全的幾種解決辦法,通常什麼地方會用到多線程?

NSThread,GCD等。儘可能用上層分裝好的方法去實現多線程而不是手動調用NSThread。

1八、怎麼理解MVC,在Cocoa中MVC是怎麼實現的?

Model: 表明你的應用程序是什麼(不是怎麼展示)

Controller: 控制你的Model怎麼展示給用戶(UI邏輯)

View: Controller的奴隸。。。

1 Model,Controller,View相互通信的規則:

Controller能夠直接和Model通訊

Controller也能夠直接和View通訊

Model和View永遠不能直接通訊

iOS中View和Controller的通訊是透明和固定的,主要經過outlet和action實現

View使用Delegate接口和Controller同步信息

View不直接和數據通訊,使用dataSource接口從Controller處獲取數據

View的delegate和dataSource通常就是Controller

Controller負責爲View翻譯和格式化Model的數據

Model使用Notification & KVO的方式分發數據更新信息,Controller能夠有選擇的監聽本身感興趣的信息。

View也能夠監聽廣播信息,但通常不是Model發出的信息

一個完整的App就是不少MVC的集合

1九、delegate和notification區別,分別在什麼狀況下使用?

Delegate:

消息的發送者(sender)告知接收者(receiver)某個事件將要發生,delegate贊成然而後發送者響應事件,delegate機制使得接收者能夠改變發送者的行爲。一般發送者和接收者的關係是直接的一對多的關係。

Notification:

消息的發送者告知接收者事件已經發生或者將要發送,僅此而已,接收者並不能反過來影響發送者的行爲。一般發送者和接收者的關係是間接的多對多關係。

1. 效率確定是delegate比nsnotification高。

2. delegate 方法比notification更加直接,最典型的特徵是,delegate方法每每須要關注返回值,也就是 delegate方法 的結果。好比-windowShouldClose:,須要關心返回的是yes仍是no。因此delegate方法每每包含should這個很傳神的詞。 也就是比如你作個人delegate,我會問你我想關閉窗口你願意嗎?你須要給我一個答案,我根據你的答案來決定如何作下一步。相反 的,notification最大的特點就是不關心接受者的態度,我只管把通告放出來,你接受不接受就是你的事情,同時我也不關心結果。因此 notification每每用did這個詞彙,好比NSWindowDidResizeNotification,那麼nswindow對象放出這個 notification後就什麼都無論了也不會等待接受者的反應。

1)兩個模塊之間聯繫不是很緊密,就用notification傳值,例如多線程之間傳值用notificaiton。

2)delegate 只是一種較爲簡單的回調,且主要用在一個模塊中,例如底層功能完成了,須要把一些值傳到上層去,就事先把上層的函數經過 delegate傳到底層,而後在底層call這個delegate,它們都在一個模塊中,完成一個功能,例如 說 NavgationController 從 B 界面到A 點返回按鈕 (調用popViewController方法) 能夠用delegate 比較好。

20、self.跟self什麼區別?

2一、id、nil表明什麼?

id 和void *並不是徹底同樣。在上面的代碼中,id是指向struct objc_object的一個指針,這個意思基本上是說,id是一個指 向任何 一個繼承了Object(或者NSObject)類的對象。須要注意的是id是一個指針,因此你在使用id的時候不須要加星號。好比id foo=nil 定義了一個nil指針,這個指針指向NSObject的一個任意子類。而id *foo=nil則定義了一個指針,這個指針指向另外一個指針,被指向的這個 指針指向NSObject的一個子類。

nil和C語言的NULL相同,在objc/objc.h中定義。nil表示一個Objctive-C對象,這個對象的指針指向空(沒有東西就是空)。

首字母大寫的Nil和nil有一點不同,Nil定義一個指向空的類(是Class,而不是對象)。

SEL是「selector」的一個類型,表示一個方法的名字

Method(咱們常說的方法)表示一種類型,這種類型與selector和實現(implementation)相關

IMP定義爲 id (*IMP) (id, SEL, …)。這樣說來, IMP是一個指向函數的指針,這個被指向的函數包括id(「self」指針),調用的SEL(方法名),再加上一些其餘參數.說白了IMP就是實現方法。

2二、內存管理 Autorelease、retain、copy、assign的set方法和含義?

1,你初始化(alloc/init)的對象,你須要釋放(release)它。例如:

NSMutableArray aArray = [[NSArray alloc] init]; 後,須要 [aArray release];

2,你retain或copy的,你須要釋放它。例如:

[aArray retain] 後,須要 [aArray release];

3,被傳遞(assign)的對象,你須要斟酌的retain和release。例如:

obj2 = [[obj1 someMethod] autorelease];

對象2接收對象1的一個自動釋放的值,或傳遞一個基本數據類型(NSInteger,NSString)時:你或但願將對象2進行retain,以防止它在被使用以前就被自動釋放掉。可是在retain後,必定要在適當的時候進行釋放。

關於索引計數(Reference Counting)的問題

retain值 = 索引計數(Reference Counting)

NSArray 對象會retain(retain值加一)任何數組中的對象。當NSArray被卸載(dealloc)的時候,全部數組中的對象會 被 執行一次釋放(retain值減一)。不只僅是NSArray,任何收集類(Collection Classes)都執行相似操做。例如 NSDictionary,甚至UINavigationController。

Alloc/init創建的對象,索引計數爲1。無需將其再次retain。

[NSArray array]和[NSDate date]等「方法」創建一個索引計數爲1的對象,可是也是一個自動釋放對象。因此是本地臨時對象,那麼無所謂了。若是是打算在全Class中使用的變量(iVar),則必須retain它。

缺省的類方法返回值都被執行了「自動釋放」方法。(*如上中的NSArray)

在類中的卸載方法「dealloc」中,release全部未被平衡的NS對象。(*全部未被autorelease,而retain值爲1的)

2三、類別的做用?

有時咱們須要在一個已經定義好的類中增長一些方法,而不想去重寫該類。好比,當工程已經很大,代碼量比較多,或者類中已經包住不少方法,已經有其餘代碼調用了該類建立對象並使用該類的方法時,能夠使用類別對該類擴充新的方法。

注意:類別只能擴充方法,而不能擴充成員變量。

2四、委託(舉例)

委託代理(degegate),顧名思義,把某個對象要作的事情委託給別的對象去作。那麼別的對象就是這個對象的代理,代替它來打理要作的事。反映到程序中,首先要明確一個對象的委託方是哪一個對象,委託所作的內容是什麼。

委託機制是一種設計模式,在不少語言中都用到的,這只是個通用的思想,網上會有不少關於這方面的介紹。

那麼在蘋果開發過程當中,用到委託的程序實現思想以下,我主要拿如何在視圖之間傳輸信息作個例子。

譬如:在兩個頁面(UIIview視圖對象)實現傳值,用委託(delegate)能夠很好作到!

方法:

類A

@interface A:UIView

id transparendValueDelegate;

@property(nomatic, retain) id transparendValueDelegate;

@end

@implemtion A

@synthesize transparendValueDelegate

-(void)Function

{

NSString* value = @"hello";

//讓代理對象執行transparendValue動做

[transparendValueDelegate transparendValue: value];

}

@end

類B

@interface B:UIView

NSString* value;

@end

@implemtion B

-(void)transparendValue:(NSString*)fromValue

{

value = fromValue;

NSLog(@"the value is %@ ",value);

}

@end

//下面的設置A代理委託對象爲B

//在定義A和B類對象處:

A* a = [[A alloc] init];

B* b = [[B alloc] init];

a. transparendValueDelegate = b;//設置對象a代理爲對象b

這樣在視圖A和B之間能夠經過委託來傳值!

2五、retainCount?

26..屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什麼做用,在那種狀況下用

assign:指定setter方法用簡單的賦值,這是默認操做。你能夠對標量類型(如int)使用這個屬性。你能夠想象一個float,它不是一個對象,因此它不能retain、copy。

retain:指定retain應該在後面的對象上調用,前一個值發送一條release消息。你能夠想象一個NSString實例,它是一個對象,並且你可能想要retain它。

copy:指定應該使用對象的副本(深度複製),前一個值發送一條release消息。基本上像retain,可是沒有增長引用計數,是分配一塊新的內存來放置它。

readonly:將只生成getter方法而不生成setter方法(getter方法沒有get前綴)。

readwrite:默認屬性,將生成不帶額外參數的getter和setter方法(setter方法只有一個參數)。

atomic:對於對象的默認屬性,就是setter/getter生成的方法是一個原子操做。若是有多個線程同時調用setter的話,不會出現某一個線程執行setter所有語句以前,另外一個線程開始執行setter的狀況,相關於方法頭尾加了鎖同樣。

nonatomic:不保證setter/getter的原子性,多線程狀況下數據可能會有問題。

27.類變量的@protected ,@private ,@public ,@package聲明各有什麼含義

Objective-C 對存取權限的設定。也是變量的做用域。

protected 該類和全部的子類中的方法能夠直接訪問這樣的變量,這是默認的。

private — 該類中的方法能夠訪問這樣的變量,子類不能夠。 public — 除了本身和子類中的方法外,也能夠被其餘類或者其餘模塊中的方法所訪問。開放性最大。 package — 對於64位圖像,這樣的成員變量能夠在實現這個類的圖像中隨意訪問。

28.淺拷貝和深拷貝區別是什麼

簡單的來講就是,在有指針的狀況下,淺拷貝只是增長了一個指針指向已經存在的內存,而深拷貝就是增長一個指針而且申請一個新的內存,使這個增長的指針指向這個新的內存,採用深拷貝的狀況下,釋放內存的時候就不會出如今淺拷貝時重複釋放同一內存的錯誤

29.Cocoa中與虛基類的概念麼?怎麼簡潔的實現

30.NSString 和 NSMutableString 有什麼區別

NSString至關於一個const char* 不能夠改變。

而 NSMutableString至關於 char* 能夠改變內部的內容。

31.自動釋放池跟GC有什麼區別?iPhone上有GC麼?[pool release] 和[pool drain]有什麼區別

」Autorelease Pools」(自動釋放池)在應用中的使用技巧。

1,Autorelease Pools概要

一 個」Autorelease Pool」實例中「包含」其它各類調用了」autorelease」方法的對象。當它釋放時,其中全部被管理對象都 會收 到」relrease」的消信。注意,同一個對象能夠被屢次調用」autorelease」方法,並能夠放到同一個」Autorelease Pool」 中。引入這個自動釋放池機制,對象的」autorelease」方法代替」relrease」方法能夠延長它的生命週期,直接到當 前」Autorelrease Pool」釋放。若是想讓此對象的生命週期超過」Autorelease Pool」,還能夠再次」retain」,呵 呵,有意思吧?且讓我慢慢道來。

Cocoa老是認爲當前至少有一個」Autorelease Pool」對象是可用的。若此對象並不存在,你調用的」autorelease」的全部對象都不會被自動釋放掉,可想而知,形成內存泄露。Cocoa把這個錯誤信息寫入日誌??僅僅是爲了之後分析。

你 能夠用」alloc」與」init」方法建立一個」NSAutoreleasePool」對象,而且能夠調用」release」或」drain」 (」release」與」drain」的區別是」drain」在有GC的環境中會引發GC回收操做,」release」反之。但在非GC環境中,二者相 同。官方的說法是爲了程序的兼容性,應該考慮用」drain」代替」release」,)方法來回收它(調用它的」autorelease」 或」retain」方法會引發異常)。在一個完整的上下文最後」Autorelease Pool」對象應該被」release」掉(在方法內或一段循環 體內建立的」Autorelease Pool」對象)。

「Autorelease Pools」的全部實例在棧中管理(咱們暫時叫他 「自動釋放池棧」),而且它們是能夠被嵌套的(父生子,子生孫。。。子 子孫 孫 ^_^)。例如,當咱們建立一個」Autorelease Pool」對象後,它就被自動放到「自動釋放池棧」的棧頂。當本池對象回收時,它就隨之從 這個棧中POP掉。那麼也就是說,當任何一個對象調用」autorelease」方法後,它會被放入當前線程中當前棧頂的自動釋放池中。

接 下來咱們聊聊」Autorelease Pools」的嵌套問題。在你的應用中,你能夠任意多的建立」Autorelease Pool」對象, 而這些 對象被當前線程的「自動釋放池棧」所管理。那麼除了一個接一個的順序建立並銷燬它的狀況外,還有一種使用方式,就是嵌套式的建立與使用。例如:在你的主函 數建立了一個」autorelease pool」,而後又調用了建立了」autorelease pool」實例的其它方法;或是在外循環中建立 了」Autorelease Pool」的實例,而內循環中也作了相同的事情。有意思吧,呵呵,嵌套的機制使父Pool實例釋放後,它的全部子Pool也 將釋放。但這裏還存在一些反作用,後續文章會詳細討論。

「Application kit」在一個事件循環裏會自動建立一個」autorelease pool」。像鼠標鍵的按下與釋放,因此你編寫的代碼一般不須要考慮太多這方面的事情。固然,有如下三種狀況你會建立與銷燬本身的Pool實例:

1,應用不是基於」Application Kit」,像」Command-line tool」,由於它並無內置的」autorelease pools」的支持。

2,建立線程,你必需在線程開始時建立一個」Autorelease Pool」實例。反之,會形成內存池露(會在之後的文章詳細說明線程與池的技巧)。

3,一個循環內建立了太多的臨時對象,你應該爲他們建立一個」Autorelease Pool」對象,並在下次循還前銷燬它們。

2,自動釋放池中的」Non-AppKit」應用

在」Non- AppKit」應用中使用自動釋放池的機制實際上是至關簡單的事情。你僅僅須要在main()起始處創 建」Autorelease Pool」 對象,並在結尾處釋放掉它。就像在Xcode的Foundation Tool的建立模版裏寫的同樣。這個確保你在應用生命週期內至少有一 個」Autorelease Pool」是可用的。可是,這也使全部在此期間的全部」autorelease」的對象都必需在應用結束後才被釋放。這也許 會引發在應用的使用中不斷的增加,因此,你仍然考慮在不一樣的做用域建立新的」Autorelease Pool」。

大多應用中都存在各類級別的循環機制。在這些應用中,你能夠在每一個循環內的開頭建立一個」Autorelease Pool」對象,並在結尾處釋放掉它。

例如:

void main()

{

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSArray *args = [[NSProcessInfo processInfo] arguments];

unsigned count, limit = [args count];

for (count = 0; count < limit; count++)

{

NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];

NSString *fileContents;

NSString *fileName;

fileName = [args objectAtIndex:count];

fileContents = [[[NSString alloc] initWithContentsOfFile:fileName] autorelease];

// this is equivalent to using stringWithContentsOfFile:

[loopPool release];

}

[pool drain];

exit (EXIT_SUCCESS);

}

在 命令行中處理全部以參數傳來的文件。一次循環處理一個文件。在循環的開頭建立一個」NSAutoreleasePool」對象,並在循環結束時釋 放掉。 所以,任何在其中建立並調用「autorelease」的對象都將添加到這個Pool實例中,當本池被釋放後,這些對象也將被回收。注意,任何在做用域內 建立的」autoreleased」對象(像」fileName」),雖然並無顯示的調用」autorelease」方法,但都將被當前池所管理並釋 放。

32.C和obj-c 如何混用

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

33.響應者鏈是什麼

響 應者鏈是Application Kit事件處理架構的中心機制。它由一系列連接在一塊兒的響應者對象組成,事件或者動做消息能夠沿着這些對象進行 傳 遞。如圖6-20顯示的那樣,若是一個響應者對象不能處理某個事件或動做-也就是說,它不響應那個消息,或者不認識那個事件,則將該消息從新發送給鏈中的 下一個響應者。消息沿着響應者鏈向上、向更高級別的對象傳遞,直到最終被處理(若是最終仍是沒有被處理,就會被拋棄)。

當 Application Kit在應用程序中構造對象時,會爲每一個窗口創建響應者鏈。響應者鏈中的基本對象是NSWindow對象及其視圖層次。 在視圖層次中級別較低的視圖將比級別更高的視圖優先得到處理事件或動做消息的機會。NSWindow中保有一個第一響應者的引用,它一般是當前窗口中處於 選擇狀態的視圖,窗口一般把響應消息的機會首先給它。對於事件消息,響應者鏈一般以發生事件的窗口對應的NSWindow對象做爲結束,雖然其它對象也可 以做爲下一個響應者被加入到NSWindow對象的後面。

34..UIscrollVew用到了什麼設計模式?還能再foundation庫中找到相似的嗎?

組合模式composition,全部的container view都用了這個模式

觀察者模式observer,全部的UIResponder都用了這個模式。

模板(Template)模式,全部datasource和delegate接口都是模板模式的典型應用

33. .timer的間隔週期準嗎?爲何?怎樣實現一個精準的timer?

NSTimer能夠精確到50-100毫秒.

NSTimer不是絕對準確的,並且中間耗時或阻塞錯過下一個點,那麼下一個點就pass過去了

此份面試題包含40個題目,是如今網上能搜索到的一個比較熱的一份,可是答案並非很詳細和完整,基本答案來着cocoaChina,和一些本身的補充。

34.Difference between shallow copy and deep copy?

淺複製和深複製的區別?

答案:淺層複製:只複製指向對象的指針,而不復制引用對象自己。

深層複製:複製引用對象自己。

意思就是說我有個A對象,複製一份後獲得A_copy對象後,對於淺複製來講,A和A_copy指向的是同一個內存資源,複製的只不過是是一個指針,對象自己資源

仍是隻有一份,那若是咱們對A_copy執行了修改操做,那麼發現A引用的對象一樣被修改,這其實違背了咱們複製拷貝的一個思想。深複製就好理解了,內存中存在了

兩份獨立對象自己。

用網上一哥們通俗的話將就是:

淺複製比如你和你的影子,你完蛋,你的影子也完蛋

深複製比如你和你的克隆人,你完蛋,你的克隆人還活着。

35.What is advantage of categories? What is difference between implementing a category and inheritance?

類別的做用?繼承和類別在實現中有何區別?

答案:category 能夠在不獲悉,不改變原來代碼的狀況下往裏面添加新的方法,只能添加,不能刪除修改。

而且若是類別和原來類中的方法產生名稱衝突,則類別將覆蓋原來的方法,由於類別具備更高的優先級。

類別主要有3個做用:

(1)將類的實現分散到多個不一樣文件或多個不一樣框架中。

(2)建立對私有方法的前向引用。

(3)向對象添加非正式協議。

繼承能夠增長,修改或者刪除方法,而且能夠增長屬性。

36.Difference between categories and extensions?

類別和類擴展的區別。

答案:category和extensions的不一樣在於後者能夠添加屬性。另外後者添加的方法是必需要實現的。

extensions能夠認爲是一個私有的Category。

37.Difference between protocol in objective c and interfaces in java?

oc中的協議和java中的接口概念有何不一樣?

答案:OC中的代理有2層含義,官方定義爲 formal和informal protocol。前者和Java接口同樣。

informal protocol中的方法屬於設計模式考慮範疇,不是必須實現的,可是若是有實現,就會改變類的屬性。

其實關於正式協議,類別和非正式協議我很早前學習的時候大體看過,也寫在了學習教程裏

「非正式協議概念其實就是類別的另外一種表達方式「這裏有一些你可能但願實現的方法,你能夠使用他們更好的完成工做」。

這個意思是,這些是可選的。好比我門要一個更好的方法,咱們就會申明一個這樣的類別去實現。而後你在後期能夠直接使用這些更好的方法。

這麼看,總以爲類別這玩意兒有點像協議的可選協議。"

如今來看,其實protocal已經開始對二者都統一和規範起來操做,由於資料中說「非正式協議使用interface修飾「,

如今咱們看到協議中兩個修飾詞:「必須實現(@requied)」和「可選實現(@optional)」。

38.What 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

{

([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就好了,

能夠按照kvc查找的邏輯理解,就說的過去了。

39.What is purpose of delegates?

代理的做用?

答案:代理的目的是改變或傳遞控制鏈。容許一個類在某些特定時刻通知到其餘類,而不須要獲取到那些類的指針。能夠減小框架複雜度。

另一點,代理能夠理解爲java中的回調監聽機制的一種相似。

40.What are mutable and immutable types in Objective C?

oc中可修改和不能夠修改類型。

答案:可修改不可修改的集合類。這個我我的簡單理解就是可動態添加修改和不可動態添加修改同樣。

好比NSArray和NSMutableArray。前者在初始化後的內存控件就是固定不可變的,後者能夠添加等,能夠動態申請新的內存空間。

41.When we call objective c is runtime language what does it mean?

咱們說的oc是動態運行時語言是什麼意思?

答案:多態。 主要是將數據類型的肯定由編譯時,推遲到了運行時。

這個問題其實淺涉及到兩個概念,運行時和多態。

簡單來講,運行時機制使咱們直到運行時纔去決定一個對象的類別,以及調用該類別對象指定方法。

多態:不一樣對象以本身的方式響應相同的消息的能力叫作多態。意思就是假設生物類(life)都用有一個相同的方法-eat;

那人類屬於生物,豬也屬於生物,都繼承了life後,實現各自的eat,可是調用是咱們只需調用各自的eat方法。

也就是不一樣的對象以本身的方式響應了相同的消息(響應了eat這個選擇器)。

所以也能夠說,運行時機制是多態的基礎?~~~

42.what is difference between NSNotification and protocol?

通知和協議的不一樣之處?

答案:協議有控制鏈(has-a)的關係,通知沒有。

首先我一開始也不太明白,什麼叫控制鏈(專業術語了~)。可是簡單分析下通知和代理的行爲模式,咱們大體能夠有本身的理解

簡單來講,通知的話,它能夠一對多,一條消息能夠發送給多個消息接受者。

代理按咱們的理解,到不是直接說不能一對多,好比咱們知道的明星經濟代理人,不少時候一個經濟人負責好幾個明星的事務。

只是對於不一樣明星間,代理的事物對象都是不同的,一一對應,不可能說明天要處理A明星要一個發佈會,代理人發出處理髮佈會的消息後,別稱B的

發佈會了。可是通知就不同,他只關心發出通知,而不關心多少接收到感興趣要處理。

所以控制鏈(has-a從英語單詞大體能夠看出,單一擁有和可控制的對應關係。

43.What is push notification?

什麼是推送消息?

答案:太簡單,不做答~~~~~~~~~~

這是cocoa上的答案。

其實到不是說太簡單,只是太泛泛的一個概念的東西。就比如說,什麼是人。

推送通知更是一種技術。

簡單點就是客戶端獲取資源的一種手段。

普通狀況下,都是客戶端主動的pull。

推送則是服務器端主動push。

44.Polymorphism?

關於多態性

答案:多態,子類指針能夠賦值給父類。

這個題目其實能夠出到一切面向對象語言中,

所以關於多態,繼承和封裝基本最好都有個自我意識的理解,也並不是必定要把書上資料上寫的能背出來。

最重要的是轉化成自我理解。

45.Singleton?

對於單例的理解

答案:11,12題目其實出的有點泛泛的感受了,可能說是編程語言須要或是必備的基礎。

基本能用熟悉的語言寫出一個單例,以及能夠運用到的場景或是你編程中碰到過運用的此種模式的框架類等。

進一步點,考慮下如何在多線程訪問單例時的安全性。

46.What is responder chain?

說說響應鏈

答案: 事件響應鏈。包括點擊事件,畫面刷新事件等。在視圖棧內從上至下,或者從下之上傳播。

能夠說點事件的分發,傳遞以及處理。具體能夠去看下touch事件這塊。由於問的太抽象化了

嚴重懷疑題目出到越後面就越籠統。

47.Difference between frame and bounds?

frame和bounds有什麼不一樣?

答案:frame指的是:該view在父view座標系統中的位置和大小。(參照點是父親的座標系統)

bounds指的是:該view在自己座標系統中 的位置和大小。(參照點是自己座標系統)

48.Difference between method and selector?

方法和選擇器有何不一樣?

答案:selector是一個方法的名字,method是一個組合體,包含了名字和實現.

詳情能夠看apple文檔。

49.Is there any garbage collection mechanism in Objective C.?

OC的垃圾回收機制?

答案: OC2.0有Garbage collection,可是iOS平臺不提供。

通常咱們瞭解的objective-c對於內存管理都是手動操做的,可是也有自動釋放池。

可是差了大部分資料,貌似不要和arc機制搞混就行了。

求更多~~

50.NSOperation queue?

答案:存放NSOperation的集合類。

操做和操做隊列,基本能夠當作java中的線程和線程池的概念。用於處理ios多線程開發的問題。

網上部分資料提到一點是,雖然是queue,可是卻並非帶有隊列的概念,放入的操做並不是是按照嚴格的先進現出。

這邊又有個疑點是,對於隊列來講,先進先出的概念是Afunc添加進隊列,Bfunc緊跟着也進入隊列,Afunc先執行這個是必然的,

可是Bfunc是等Afunc徹底操做完之後,B纔開始啓動而且執行,所以隊列的概念離亂上有點違背了多線程處理這個概念。

可是轉念一想其實能夠參考銀行的取票和叫號系統。

所以對於A比B先排隊取票可是B率先執行完操做,咱們亦然能夠感性認爲這仍是一個隊列。

可是後來看到一票關於這操做隊列話題的文章,其中有一句提到

「由於兩個操做提交的時間間隔很近,線程池中的線程,誰先啓動是不定的。」

瞬間以爲這個queue名字有點忽悠人了,還不如pool~

綜合一點,咱們知道他能夠比較大的用處在於能夠幫組多線程編程就行了。

51.What is lazy loading?

答案:懶漢模式,只在用到的時候纔去初始化。

也能夠理解成延時加載。

我以爲最好也最簡單的一個列子就是tableView中圖片的加載顯示了。

一個延時載,避免內存太高,一個異步加載,避免線程堵塞。

52.Can we use two tableview controllers on one viewcontroller?

是否在一個視圖控制器中嵌入兩個tableview控制器?

答案:一個視圖控制只提供了一個View視圖,理論上一個tableViewController也不能放吧,

只能說能夠嵌入一個tableview視圖。固然,題目自己也有歧義,若是不是咱們定性思惟認爲的UIViewController,

而是宏觀的表示視圖控制者,那咱們卻是能夠把其當作一個視圖控制者,它能夠控制多個視圖控制器,好比TabbarController

那樣的感受。

53.Can we use one tableview with two different datasources? How you will achieve this?

一個tableView是否能夠關聯兩個不一樣的數據源?你會怎麼處理?

答案:首先咱們從代碼來看,數據源如何關聯上的,實際上是在數據源關聯的代理方法裏實現的。

所以咱們並不關心如何去關聯他,他怎麼關聯上,方法只是讓我返回根據本身的須要去設置如相關的數據源。

 

所以,我以爲能夠設置多個數據源啊,可是有個問題是,你這是想幹嗎呢?想讓列表如何顯示,不一樣的數據源分區塊顯示?

 
 
 
 

ios面試攻略(1.1)  

2013-10-22 20:27:37|  分類: IOS面試 |  標籤:ios  面試  |舉報|字號 訂閱

 
 
 
 
1.Object-c的類能夠多重繼承麼?能夠實現多個接口麼??
沒有,protocol  代替,Object-c的類不能夠多重繼承。
2.#import 跟#include 又什麼區別,@class呢; #import<> 跟 #import」"又什麼區別?? 
#import 能防止重複引用,#include 不能,@class 前置聲明一個類。
3.屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什麼做用,在那種狀況下用 ?
四、爲何不少內置的類,如TableViewController的delegate的屬性是assign不是retain?
防止循環引用。
五、定義屬性時,什麼狀況使用copy、assign、retain??
copy:拷貝對象。assign:傳值,通常用於基礎類型。retain:傳地址,引用計數器加一。
6,委託是什麼?委託的property聲明用什麼屬性?爲何?
代理的目的是改變或傳遞控制鏈,容許一個類在某些特定時刻通知到其餘類而不須要獲取那些類的指針。
7,類別的做用?
1),將類的實現分散到多個類中2),建立對私有方法的引用3),能夠添加或修改方法,屬性
8,.id 聲明的對象有什麼特性??
能夠是任意類型的對象,是個很重要的類型,是個能夠指向任何類型的指針或者能夠理解爲指向任何未知類型的指針。
9,.MVC是什麼?有什麼特性?爲何在iPhone上被普遍運用?
MVC設計模式是三種對象:模型對象,視圖對象和控制器對象。模型對象表明應用程序的數據和定義操做數據的邏輯。視圖對象顯示應用程序的模型數據。控制器對象是協調視圖和模型對象。
10,對於語句NSString* testObject = [[NSData alloc] init];testObject 在編譯時和運行時分別是什麼類型的對象?
11.什麼是安全釋放?
12,爲何有些4.0獨有的objective-c 函數在3.1上運行時會報錯.而4.0獨有的類在3.1上分配內存時不會報錯?分配的結果是什麼?
13,爲何4.0獨有的c函數在3.1的機器上運行不會報錯(在沒有調用的狀況下?)而4.0獨有的類名在3.1的機器上一運行就報錯?
?14,常見的object-c的數據類型有那些, 和 c 的 基本數據類型有什麼區別?如:nsinteger 和int
15,.property中屬性retain,copy,assgin的含義分別是什麼?有什麼區別?將其轉換成get/set方法怎麼作?有什麼注意事項?
1六、什麼是Notification? 
Notification是一種消息,它傳遞給一個或多個觀察對象用來通知它們程序裏發生了一個事件。
1七、何時用delegate,何時用Notification?
當處理單個須要在另外類觸發當前類行爲的事件時用代理,多個事件用 Notification.
1八、線程理解,有什麼好處?
線程建立和啓動,NSThread  detachNew建立和NSThread 建立兩中方式
線程共享同一應用程序的部份內存空間它們擁有對數據相同的訪問權限
19.線程和進程的區別和聯繫?
線程和進程都是程序運行的基本單元,區別在於進程在運行中擁有獨立的內存單元,而多個線程共享內存,提升程序效率,線程不能獨立執行。
20,線程是什麼? 有哪些注意事項.?
21,.notification是同步仍是異步? kvo是同步仍是異步?notification是全進程空間的通知嗎?
22.淺拷貝和深拷貝區別是什麼?…
淺複製:只複製指向對象的指針,而不復制引用對象自己。深複製:複製引用對象自己。
23,.NSString 和 NSMutableString 有什麼區別?
24.for(int index = 0; index < 20; index ++){?    NSString *tempStr = @」tempStr」;?    NSLog(tempStr);?    NSNumber *tempNumber = [NSNumber numberWithInt:2];?    NSLog(tempNumber);?}?這段代碼有什麼問題.?會不會形成內存泄露(多線程)?在內存緊張的設備上作大循環時自動釋放池是寫在循環內好仍是循環外好?爲何?
25,.內存管理的幾條原則時什麼?按照默認法則.那些關鍵字生成的對象須要手動釋放?在和property結合的時候怎樣有效的避免內存泄露?
26,.在一個對象釋放前.若是他被加到了notificationCenter 中.不在notificationcenter中remove這個對象可能會出現什麼問題?
27,.怎樣實現一個 singleton的類.給出思路。
單例是在程序生命週期裏只被實例化過一次的 類
28.什麼是序列化或者Acrchiving,能夠用來作什麼,怎樣與copy結合,原理是什麼?.
29.在iphone上有兩件事情要作,請問是在一個線程裏按順序作效率高仍是兩個線程裏作效率高?爲何?
30,.runloop是什麼?在主線程中的某個函數裏調用了異步函數,怎麼樣block當前線程,且還能響應當前線程的timer事件,touch事件等.
31,ios平臺怎麼作數據的持久化?coredata和sqlite有無必然聯繫?coredata是一個關係型數據庫嗎?
32.闡述一個nil對象從interface bulider產生,到載入程序運行空間,最後被釋放時所經歷的生命週期.
33,響應者鏈是什麼?
34,.timer的間隔週期準嗎?爲何?怎樣實現一個精準的timer?
35.UIscrollVew用到了什麼設計模式?還能再foundation庫中找到相似的嗎?
36.C和obj-c 如何混用?
37,ViewController 的 loadView, viewDidLoad, viewDidUnload 分別是在何時調用的?
view爲空時調用loadView,加載完成時調用viewDidLoad,釋放時調用viewDidUnload.
38.ViewController 的 didReceiveMemoryWarning 是在何時被調用的?
39.談談你對ARC 的認識和理解?
代碼中自動加入了retain/release,原先須要手動添加的用來處理內存管理的引用計數的代碼能夠自動地由編譯器完成了,代碼高速化,因爲使用編譯器管理引用計數,減小了低效代碼的可能性
40, Object-C有私有方法嗎?私有變量呢??沒,有。
4一、Object-C的內存管理??引用計數器。??
4二、對象是何時被release的??引用計數器爲0.
4三、iOS有沒有垃圾回收??沒。
4四、tableView的重用機制??複用標記。
4五、ViewController 的loadView、viewDidLoad、viewDidUnload分別是何時調用的,在自定義ViewController時在這幾個函數中應該作什麼工做??當view爲nil時調用loadView,view完成加載調用viewDidLoad,view釋放時調用viewDidUnload.?
4六、ViewController的didReceiveMemoryWarning是在何時調用的?默認的操做是什麼??內存超過闕值,嘗試釋放view.
4七、列舉Cocoa中常見的幾種多線程的實現,並談談多線程安全的幾種解決辦法,通常什麼地方會用到多線程??NSThread,GCD等。儘可能用上層分裝好的方法去實現多線程而不是手動調用NSThread。
4八、self.跟self什麼區別?
self.表示對象的屬性,self表示對象自己
4九、id、nil表明什麼??id至關於void*,nil是空對象。
50、ObjC中,與alloc語義相反的方法是dealloc仍是release?與retain語義相反的方法是dealloc仍是release,爲何?須要與alloc配對使用的方法是dealloc仍是release,爲何??
5一、autorelease的對象是在何時被release的?
自動釋放池中全部對象釋放完後釋放。
5二、這段代碼有什麼問題,如何修改?for (int i = 0; i < someLargeNumber; i++) { ?NSString *string = @」Abc」;?string = [string lowercaseString];?string = [string stringByAppendingString:@"xyz"];?NSLog(@「%@」, string);?} ?5三、autorelease和垃圾回收機制(gc)有什麼關係? 
內存釋放池提供了一個對象容器,每次對象發送autorelease消息時,對象的引用計數並不真正變化,而是向內存釋放池中添加一條記錄,記下對象的這 種要求。直到當內存釋放池發送drain或release消息時,即當池被銷燬前會通知池中的全部對象,所有發送release消息纔會真正將引用計數減 少?。?
5四、考察對@interface與@propety的理解
只用 @ interface聲明的變量只能在當前的類中訪問,在其餘類沒法訪問,而@ propety聲明的變量能夠在外部訪問。@ propety聲明的變量能夠打點調用
5五、objective-c中的類型轉換分爲哪幾類
字符串拼接,強制類型轉換
5六、多態的理解
Object-C是面向對象的編程語言,它具備面向對象編程的一些特性,封裝性,繼承性和多態性。不一樣對象以本身的方式響應相同的消息的能力叫多態。多態的主要好處就是簡化了編程接口,
 

騰訊面試題
1。簡述push原理,push的證書和其它的右什麼不同?
2。viewcontroller的一些方法的說明viewDidLoad, viewWillDisappear, viewWillAppear方法的 順序和 做用?
3。frame 和 bounds 的 區別 ,bound的大小改變frame 改變嗎?
4。sqlite中插入特殊字符的方法和接收處處理方法。
5。談談你對數組和鏈表認識,還有你是怎麼用他們的?
6。冒泡算法。
7。socket編程簡述
8。asihttp代碼原理 ,異步請求的原理,異步請求最大數目,爲何只能這麼多?
9。http請求方式?
10。uiview的圓角屬性設置方法。
(m_mainImgView.layer.cornerRadius = 6;
m_mainImgView.layer.masksToBounds = YES;)
11。 masksToBounds屬性的做用。(決定子layer是否被當前layer的邊界剪切。默認是NO。)
 
 
 
 
閱讀(203)評論(0)
 

來自網絡

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],執行結果是2,5

   &a+1不是首地址+1,系統會認爲加一個a數組的偏移,是偏移了一個數組的大小(本例是5個int)

   int *ptr=(int *)(&a+1);

   則ptr實際是&(a[5]),也就是a+5

 緣由以下:

  &a是數組指針,其類型爲 int (*)[5];

   而指針加1要根據指針類型加上必定的值,不一樣類型的指針+1以後增長的大小不一樣。

   a是長度爲5的int數組指針,因此要加 5*sizeof(int)

   因此ptr實際是a[5]

   可是prt與(&a+1)類型是不同的(這點很重要)

   因此prt-1只會減去sizeof(int*)

  a,&a的地址是同樣的,但意思不同

     a是數組首地址,也就是a[0]的地址,&a是對象(數組)首地址,

     a+1是數組下一元素的地址,即a[1],&a+1是下一個對象的地址,即a[5].

 

2.如下爲Windows NT下的32位C++程序,請計算sizeof的值

void Func ( char str[100] )

 { sizeof( str ) = ? }

 void *p = malloc( 100 );

 sizeof ( p ) = ?

答:4,4

這題很常見了,Func ( char str[100] )函數中數組名做爲函數形參時,在函數體內,數組名失去了自己的內涵,僅僅只是一個指針;在失去其內涵的同時,它還失去了其常量特性,能夠做自增、自減等操做,能夠被修改。Windows NT 32位平臺下,指針的長度(佔用內存的大小)爲4字節,故sizeof( str ) 、sizeof ( p ) 都爲4。

 

3.仍是考指針,不過我對cocoa的代碼仍是不太熟悉

大概是這樣的

-(void)*getNSString(const NSString * inputString)

{inputString = @"This is a main test\n";

 return ;}

-main(void)

{ NSString *a=@"Main";

 NSString *aString = [NSString stringWithString:@"%@",getNSString(a)];

 NSLog(@"%@\n", aString); }

 

最後問輸出的字符串:NULL,output在函數返回後,內存已經被釋放。

 

4.用預處理指令#define聲明一個常數,用以代表1年中有多少秒(忽略閏年問題)

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

我在這想看到幾件事情:

 ?; #define 語法的基本知識(例如:不能以分號結束,括號的使用,等等)

 ?; 懂得預處理器將爲你計算常數表達式的值,所以,直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的。

 ?; 意識到這個表達式將使一個16位機的整型數溢出-所以要用到長整型符號L,告訴編譯器這個常數是的長整型數。

 ?; 若是你在你的表達式中用到UL(表示無符號長整型),那麼你有了一個好的起點。記住,第一印象很重要。

寫一個"標準"宏MIN,這個宏輸入兩個參數並返回較小的一個。

#define MIN(A,B)((A) <= (B) ? (A) : (B))

 這個測試是爲下面的目的而設的:

 ?;標識#define在宏中應用的基本知識。這是很重要的,由於直到嵌入(inline)操做符變爲標準C的一部分,宏是方便產生嵌入代碼的惟一方

 法,對於嵌入式系統來講,爲了能達到要求的性能,嵌入代碼常常是必須的方法。

?;三重條件操做符的知識。這個操做符存在C語言中的緣由是它使得編譯器能產生比 if-then-else更優化的代碼,瞭解這個用法是很重要的。

 ?; 懂得在宏中當心地把參數用括號括起來

 ?;我也用這個問題開始討論宏的反作用,例如:當你寫下面的代碼時會發生什麼事?

    least = MIN(*p++, b);

結果是:

 ((*p++) <= (b) ? (*p++) : (*p++))

 這個表達式會產生反作用,指針p會做三次++自增操做。

 

5.寫一個委託的interface

@protocol MyDelegate;

@interface MyClass: NSObject

{    id <MyDelegate> delegate; }

//委託方法

@protocol MyDelegate

- (void)didJobs:(NSArray *)args;

@end

6.寫一個NSString類的實現

+ (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;

+ (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中全部的類都是NSObject的子類

多繼承在這裏是用protocol委託代理來實現的

你不用去考慮繁瑣的多繼承,虛基類的概念.

 ood的多態特性  在obj-c中經過委託來實現.

8.obj-c有私有方法麼?私有變量呢

 objective-c -類裏面的方法只有兩種, 靜態方法和實例方法. 這彷佛就不是完整的面向對象了,按照OO的原則就是一個對象只暴露有用的東西. 若是沒有了私有方法的話, 對於一些小範圍的代碼重用就不那麼順手了. 在類裏面聲名一個私有方法

@interface Controller : NSObject { NSString *something; }

+ (void)thisIsAStaticMethod;

- (void)thisIsAnInstanceMethod;

@end

@interface Controller (private) -

(void)thisIsAPrivateMethod;

@end

@private能夠用來修飾私有變量

Objective‐C中,全部實例變量默認都是私有的,全部實例方法默認都是公有的

 

9.關鍵字const有什麼含意?修飾類呢?static的做用,用於類呢?還有extern c的做用

const意味着"只讀",下面的聲明都是什麼意思?

 const int a;

 int const a;

 const int *a;

 int * const a;

 int const * a const;

前兩個的做用是同樣,a是一個常整型數。第三個意味着a是一個指向常整型數的指針(也就是,整型數是不可修改的,但指針能夠)。第四個意思a是一個指向整型數的常指針(也就是說,指針指向的整型數是能夠修改的,但指針是不可修改的)。最後一個意味着a是一個指向常整型數的常指針(也就是說,指針指向的整型數是不可修改的,同時指針也是不可修改的)。

 結論:

?;關鍵字const的做用是爲給讀你代碼的人傳達很是有用的信息,實際上,聲明一個參數爲常量是爲了告訴了用戶這個參數的應用目的。若是

 你曾花不少時間清理其它人留下的垃圾,你就會很快學會感謝這點多餘的信息。(固然,懂得用const的程序員不多會留下的垃圾讓別人來清

 理的。)

 ?; 經過給優化器一些附加的信息,使用關鍵字const也許能產生更緊湊的代碼。

 ?; 合理地使用關鍵字const能夠使編譯器很天然地保護那些不但願被改變的參數,防止其被無心的代碼修改。簡而言之,這樣能夠減小bug的出現。 

1)欲阻止一個變量被改變,能夠使用 const 關鍵字。在定義該 const 變量時,一般須要對它進行初

 始化,由於之後就沒有機會再去改變它了;

 (2)對指針來講,能夠指定指針自己爲 const,也能夠指定指針所指的數據爲 const,或兩者同時指

 定爲 const;

 (3)在一個函數聲明中,const 能夠修飾形參,代表它是一個輸入參數,在函數內部不能改變其值;

 (4)對於類的成員函數,若指定其爲 const 類型,則代表其是一個常函數,不能修改類的成員變量;

 (5)對於類的成員函數,有時候必須指定其返回值爲 const 類型,以使得其返回值不爲「左值」。

 

關鍵字volatile有什麼含意?並給出三個不一樣的例子。

一個定義爲volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到

 這個變量時必須每次都當心地從新讀取這個變量的值,而不是使用保存在寄存器裏的備份。下面是volatile變量的幾個例子: 

?;並行設備的硬件寄存器(如:狀態寄存器)

 ?; 一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables) ?; 多線程應用中被幾個任務共享的變量

?;一個參數既能夠是const還能夠是volatile嗎?解釋爲何。

 ?; 一個指針能夠是volatile 嗎?解釋爲何。

 

 下面是答案:

 ?; 是的。一個例子是隻讀的狀態寄存器。它是volatile由於它可能被意想不到地改變。它是const由於程序不該該試圖去修改它。

 ?; 是的。儘管這並不很常見。一個例子是當一箇中服務子程序修該一個指向一個buffer的指針時。 

 

static關鍵字的做用:

1)函數體內 static 變量的做用範圍爲該函數體,不一樣於 auto 變量,該變量的內存只被分配一次,

 所以其值在下次調用時仍維持上次的值;

 (2)在模塊內的 static 全局變量能夠被模塊內所用函數訪問,但不能被模塊外其它函數訪問;

 (3)在模塊內的 static 函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明

 它的模塊內;

 (4)在類中的 static 成員變量屬於整個類所擁有,對類的全部對象只有一份拷貝;

 (5)在類中的 static 成員函數屬於整個類所擁有,這個函數不接收 this 指針,於是只能訪問類的static 成員變量。

extern "C"的做用

1)被 extern "C"限定的函數或變量是 extern 類型的;

       extern是 C/C++語言中代表函數和全局變量做用範圍(可見性)的關鍵字,該關鍵字告訴編譯器,

 其聲明的函數和變量能夠在本模塊或其它模塊中使用。

2)被 extern "C"修飾的變量和函數是按照 C 語言方式編譯和鏈接的;

 

extern "C"的慣用法

1)在 C++中引用 C 語言中的函數和變量,在包含 C 語言頭文件(假設爲 cExample.h)時,需進

 行下列處理:

 extern "C"

 {  #include "cExample.h"   }

 而在 C 語言的頭文件中,對其外部函數只能指定爲 extern 類型,C 語言中不支持 extern "C"聲明,

 在.c 文件中包含了 extern "C"時會出現編譯語法錯誤。

2)在 C 中引用 C++語言中的函數和變量時,C++的頭文件需添加 extern "C",可是在 C 語言中不

 能直接引用聲明瞭 extern "C"的該頭文件,應該僅將 C 文件中將 C++中定義的 extern "C"函數聲明爲

 extern 類型。

10.爲何標準頭文件都有相似如下的結構?

   #ifndef __INCvxWorksh

    #define __INCvxWorksh

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*...*/

    #ifdef __cplusplus

    }

    #endif

    #endif /* __INCvxWorksh */

顯然,頭文件中的編譯宏「#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif」 的做用

 是防止該頭文件被重複引用。

 
 
 

ios面試攻略(2.1)  

2013-10-24 15:53:54|  分類: IOS面試 |  標籤:ios面試題目  |舉報|字號 訂閱

 
 

11.#import#include的區別,@class呢?

 @class通常用於頭文件中須要聲明該類的某個實例變量的時候用到,在m文件中仍是須要使用#import

#import比起#include的好處就是不會引發交叉編譯

12.MVC模式的理解

MVC設計模式考慮三種對象:模型對象、視圖對象、和控制器對象。模型對象表明特別的知識和專業技能,它們負責保有應用程序的數據和定義操做數據的邏輯。視圖對象知道如何顯示應用程序的模型數據,並且可能容許用戶對其進行編輯。控制器對象是應用程序的視圖對象和模型對象之間的協調者。

13.線程與進程的區別和聯繫?

進程和線程都是由操做系統所 體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。

程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。

Add

進程和線程都是由操做系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。進程和線程的區別在於:

簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.

線程的劃分尺度小於進程,使得多線程程序的併發性高。

另外,進程在執行過程當中擁有獨立的內存單元,而多個線程共享內存,從而極大地提升了程序的運行效率。

線程在執行過程當中與進程仍是有區別的。每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分能夠同時執行。但操做系統並無將多個線程看作多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源.

一個線程能夠建立和撤銷另外一個線程;同一個進程中的多個線程之間能夠併發執行.

///

14.列舉幾種進程的同步機制,並比較其優缺點。

答案:  原子操做 信號量機制    自旋鎖    管程,會合,分佈式系統

 進程之間通訊的途徑

答案:共享存儲系統消息傳遞系統管道:以文件系統爲基礎

 進程死鎖的緣由

答案:資源競爭及進程推動順序非法

 死鎖的4個必要條件

答案:互斥、請求保持、不可剝奪、環路

 死鎖的處理

答案:鴕鳥策略、預防策略、避免策略、檢測與解除死鎖

15.堆和棧的區別

管理方式:對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來講,釋放工做由程序員控制,容易產生memory leak。

申請大小:

 棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就肯定的常數),若是申請的空間超過棧的剩餘空間時,將提示overflow。所以,能從棧得到的空間較小。

 堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是因爲系統是用鏈表來存儲的空閒內存地址的,天然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。

 

碎片問題:對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降。對於棧來說,則不會存在這個問題,由於棧是先進後出的隊列,他們是如此的一一對應,以致於永遠都不可能有一個內存塊從棧中間彈出

分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,好比局部變量的分配。動態分配由alloca函數進行分配,可是棧的動態分配和堆是不一樣的,他的動態分配是由編譯器進行釋放,無需咱們手工實現。

分配效率:棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的。

16.什麼是鍵-值,鍵路徑是什麼

模型的性質是經過一個簡單的鍵(一般是個字符串)來指定的。視圖和控制器經過鍵來查找相應的屬性值。在一個給定的實體中,同一個屬性的全部值具備相同的數據類型。鍵-值編碼技術用於進行這樣的查找—它是一種間接訪問對象屬性的機制。

鍵路徑是一個由用點做分隔符的鍵組成的字符串,用於指定一個鏈接在一塊兒的對象性質序列。第一個鍵的性質是由先前的性質決定的,接下來每一個鍵的值也是相對於其前面的性質。鍵路徑使您能夠以獨立於模型實現的方式指定相關對象的性質。經過鍵路徑,您能夠指定對象圖中的一個任意深度的路徑,使其指向相關對象的特定屬性。

For example, the key path address.streetwould get the value of the address property from the receiving

object, and then determine the street property relative to the address object.

 

17.cobj-c如何混用

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.

 

18.目標-動做機制

目標是動做消息的接收者。一個控件,或者更爲常見的是它的單元,以插座變量(參見"插座變量"部分)

 的形式保有其動做消息的目標。

動做是控件發送給目標的消息,或者從目標的角度看,它是目標爲了響應動做而實現的方法。

程序須要某些機制來進行事件和指令的翻譯。這個機制就是目標-動做機制。

 

19.cocoa touch框架

iPhoneOS應用程序的基礎 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

網絡/li>

Bonjour

WebKit

BSD Sockets

用戶應用

Address Book

Core Location

Map Kit

Store Kit

 

20.objc的內存管理

 若是您經過分配和初始化(好比[[MyClass alloc] init])的方式來建立對象,您就擁有這個對象,須要負責該對象的釋放。這個規則在使用NSObject的便利方法new 時也一樣適用。

若是您拷貝一個對象,您也擁有拷貝獲得的對象,須要負責該對象的釋放。

若是您保持一個對象,您就部分擁有這個對象,須要在再也不使用時釋放該對象。反過來,

若是您從其它對象那裏接收到一個對象,則您不擁有該對象,也不該該釋放它(這個規則有少數的例外,在參考文檔中有顯式的說明)。

 

21.自動釋放池是什麼,如何工做

當您向一個對象發送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。它仍然是個正當的對象,所以自動釋放池定義的做用域內的其它對象能夠向它發送消息。當程序執行到做用域結束的位置時,自動釋放池就會被釋放,池中的全部對象也就被釋放。

 

1.  ojc-c是經過一種"referring counting"(引用計數)的方式來管理內存的, 對象在開始分配內存(alloc)的時候引用計數爲一,之後每當碰到有copy,retain的時候引用計數都會加一, 每當碰到release和autorelease的時候引用計數就會減一,若是此對象的計數變爲了0, 就會被系統銷燬.

 2. NSAutoreleasePool 就是用來作引用計數的管理工做的,這個東西通常不用你管的.

 3. autorelease和release沒什麼區別,只是引用計數減一的時機不一樣而已,autorelease會在對象的使用真正結束的時候才作引用計數減一.

 

22.類工廠方法是什麼

類工廠方法的實現是爲了向客戶提供方便,它們將分配和初始化合在一個步驟中,返回被建立的對象,並進行自動釋放處理。這些方法的形式是+ (type)className...(其中 className不包括任何前綴)。工廠方法可能不只僅爲了方便使用。它們不但能夠將分配和初始化合在一塊兒,還能夠爲初始化過程提供對象的分配信息。類工廠方法的另外一個目的是使類(好比NSWorkspace)提供單件實例。雖然init...方法能夠確認一 個類在每次程序運行過程只存在一個實例,但它須要首先分配一個「生的」實例,而後還必須釋放該實例。工廠方法則能夠避免爲可能沒有用的對象盲目分配內存。

 

23.單件實例是什麼

Foundation和 Application Kit 框架中的一些類只容許建立單件對象,即這些類在當前進程中的惟一實例。舉例來講,NSFileManager 和NSWorkspace 類在使用時都是基於進程進行單件對象的實例化。當向這些類請求實例的時候,它們會向您傳遞單一實例的一個引用,若是該實例還不存在,則首先進行實例的分配和初始化。單件對象充當控制中心的角色,負責指引或協調類的各類服務。若是類在概念上只有一個實例(好比NSWorkspace),就應該產生一個單件實例,而不是多個實例;若是未來某一天可能有多個實例,您能夠使用單件實例機制,而不是工廠方法或函數。

 

24.動態綁定

—在運行時肯定要調用的方法

動態綁定將調用方法的肯定也推遲到運行時。在編譯時,方法的調用並不和代碼綁定在一塊兒,只有在消實發送出來以後,才肯定被調用的代碼。經過動態類型和動態綁定技術,您的代碼每次執行均可以獲得不一樣的結果。運行時因子負責肯定消息的接收者和被調用的方法。運行時的消息分發機制爲動態綁定提供支持。當您向一個動態類型肯定了的對象發送消息時,運行環境系統會經過接收者的isa指針定位對象的類,並以此爲起點肯定被調用的方法,方法和消息是動態綁定的。並且,您沒必要在Objective-C 代碼中作任何工做,就能夠自動獲取動態綁定的好處。您在每次發送消息時,特別是當消息的接收者是動態類型已經肯定的對象時,動態綁定就會例行而透明地發生。

 

25.obj-c的優缺點

objc優勢:

   1) Cateogies

   2) Posing

   3) 動態識別

   4) 指標計算

   5)彈性訊息傳遞

   6) 不是一個過分複雜的 C 衍生語言

   7) Objective-C 與 C++ 可混合編程

 缺點:

   1) 不支援命名空間

   2)  不支持運算符重載

  3) 不支持多重繼承

  4) 使用動態運行時類型,全部的方法都是函數調用,因此不少編譯時優化方法都用不到。(如內聯函數等),性能低劣。

 

26.sprintf,strcpy,memcpy使用上有什麼要注意的地方

strcpy是一個字符串拷貝的函數,它的函數原型爲strcpy(char *dst, const char *src);

src開始的一段字符串拷貝到dst開始的內存中去,結束的標誌符號爲'\0',因爲拷貝的長度不是由咱們本身控制的,因此這個字符串拷貝很容易出錯。具有字符串拷貝功能的函數有memcpy,這是一個內存拷貝函數,它的函數原型爲memcpy(char *dst, const char* src, unsigned int len);

將長度爲len的一段內存,從src拷貝到dst中去,這個函數的長度可控。可是會有內存疊加的問題。

sprintf是格式化函數。將一段數據經過特定的格式,格式化到一個字符串緩衝區中去。sprintf格式化的函數的長度不可控,有可能格式化後的字符串會超出緩衝區的大小,形成溢出。

 

27.用變量a給出下面的定義 

a)一個整型數(An integer) 

 b)一個指向整型數的指針( A pointer to an integer) 

 c)一個指向指針的的指針,它指向的指針是指向一個整型數( A pointer to a pointer to an intege)

 d)一個有10個整型數的數組( An array of 10 integers) 

 e) 一個有10個指針的數組,該指針是指向一個整型數的。(An array of 10 pointers to integers) 

 f) 一個指向有10個整型數數組的指針( A pointer to an array of 10 integers) 

 g) 一個指向函數的指針,該函數有一個整型參數並返回一個整型數(A pointer to a function that takes an integer as an argument  and returns an integer) 

 h)一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數( 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 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 functions  that take an integer argument and return an integer

 

 

 

ios面試攻略(3.0)  

2013-10-26 21:02:14|  分類: IOS面試 |  標籤:ios面試題  |舉報|字號 訂閱

 
 

來自:藍色維度

1、屬性相關

1.在一個對象的方法裏面: self.name = 「object」; 和 name =」object」 有什麼不一樣嗎?
答:self.name = 「object」會調用對象的setName()方法,name = 「object」會直接把object賦值給當前對象的name屬性。
2.這段代碼有什麼問題嗎:
@implementation Person
- (void)setAge:(int)newAge {

self.age = newAge;
}
答:在進行age屬性進行.的賦值時,會調用此方法的setAge方法,這樣會進入無休止的循環調用中致使crash.
3.定義屬性時,什麼狀況使用copy,assign,和retain?
答:readwrite 是可讀可寫特性;須要生成getter方法和setter方法時
readonly 是隻讀特性 只會生成getter方法 不會生成setter方法 ;不但願屬性在類外改變
assign 是賦值特性setter方法將傳入參數賦值給實例變量;僅設置變量時;
retain 表示持有特性setter方法將傳入參數先保留,再賦值,傳入參數的retain count會+1;
copy 表示賦值特性setter方法將傳入對象複製一份;須要徹底複製一份新的變量時。
// more
nonatomic 非原子操做,決定編譯器生成的setter getter是不是原子操做,atomic表示多線程安全,通常使用nonatomic
assign用於簡單數據類型,如NSInteger,double,bool,retain 和copy用戶對象,copy用於當 a指向一個對象,b也想指向一樣的對象的時候,若是用assign,a若是釋放,再調用b會crash,若是用copy 的方式,a和b各自有本身的內存,就能夠解決這個問題。retain 會使計數器加一,也能夠解決assign的問題。另外:atomic和nonatomic用來決定編譯器生成的getter和setter是否爲原子操做。在多線程環境下,原子操做是必要的,不然有可能引發錯誤的結果。加了atomic,setter函數會變成下面這樣:
if (property != newValue) {
[property release];
property = [newValue retain];
}

4.寫一個setter方法用於完成@property (nonatomic,retain)NSString *name,
寫一個setter方法用於完成@property(nonatomic,copy)NSString *name
答:// 這裏主要是注意順序,先要reain傳入參數,再release原來的屬性。防止name和str是同一個變量時發生錯誤。
// retain
- (void) setName : (NSString*) str {
[str retain];
[name release];
name = str;
}
// copy
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}

5.爲何不少內置類如UITableViewController的delegate屬性都是assign而不是retain的?
答:會引發循環引用,致使內存沒法釋放

 

2、UIViewController

1.ViewController 的 loadView, viewDidLoad, viewDidUnload 分別是在何時調用的?
在自定義ViewController的時候這幾個函數裏面應該作什麼工做?
答:當ViewControll被初始化後,調用self.view屬性時,若是view爲nil的話,會調用loadView方法。loadView方法調用完成後,會調用viewDidLoad。
ViewController收到內存不足的警告時,6.0如下版本會調用viewDidUnload方法。
這三個方法,在調用時,首先應該調用super類的同名方法,不然有可能引發循環調用crash。
loadView通常用於使用xib文件的狀況,咱們能夠不重寫這個方法。
viewDidLoad裏能夠加載一些咱們本身的view。
viewDidUnload裏實現將retain 的view release,若是是retain的IBOutlet view 屬性則不要在這裏release,IBOutlet會負責release 。
loadView和viewDidLoad裏面加載的內容和viewDidUnload裏面卸載的內容應該對應,不然容易內存泄露或者過分釋放。

2.ViewController 的 didReceiveMemoryWarning 是在何時被調用的?默認的操做是什麼?
答:當ViewController收到內存不足的警告時,6.0如下版本會調用viewDidUnload方法。
默認操做是調用super的同名方法,將viewController的view的全部subView移除,將view自己釋放。

  

3、C語言相關

1.sizeof與strlen的區別和聯繫?
答:二者的聯繫是,均可以返回一個長度。
sizeof返回的是變量或類型所佔的字節數。strlen返回的是字符串的長度。
sizeof是關鍵字,strlen是庫函數。

2. 下列兩行代碼有什麼區別?
char a[] = 「string」;
char *b = 「string」;
a是字符數組,b一個字符串,二者sizeof取值不一樣。

3. 下列代碼會輸出什麼?
#define SQ(x) (x*x)
int main()
{
int b = 3;
int a = SQ(b + 2);
printf(「%d」, a);
return 0;
}

=b+2*b+2

11,不是25.主是要宏的直接替換問題。定義宏的時候元素上要加小括號.

4. 下列代碼有什麼問題?
char *foo(int n)
{
char buf[32];
buf[0] = (n != 0) ? ‘T’ : ‘F’;
buf[1] = 0;
return buf;
}
返回的是野指針。

5. 下列代碼有什麼問題?如有錯誤請改正。
void swap(int *p1, int *p2)
{
int *p = p1;
p1 = p2;
p2 = p;
}
沒法實現交換兩個指針,參數應該用指針的指針。

6. 若 char *p = malloc(32); 則 sizeof(p) 的值是什麼?
32位機器上是4

7. 用遞歸方式和非遞歸方式寫函數將一個字符串按字節反轉,函數原型以下:
char *reverse(char *str);
非遞歸:
char *reverse(char *str)
{
if (str == NULL || strlen(str) <= 1) {
return str;
}
int len = strlen(str);
char* b = (char*)malloc(len+1);// 外部去釋放
strcpy(b, str);
for (int i=0; i
 char x = b[i];
b[i] = b[len-i-1];
b[len-i-1] = x;
}

return b;
}

遞歸:
char *reverse(char *str)
{
if (str == NULL || strlen(str) <= 1) {
return str;
}

int len = strlen(str);

char e[] = {str[len-1],0};
char s[] = {str[0],0};

char* b = (char*)malloc(len-1);
strncpy(b, str+1,len-2);

char* c = (char*)malloc(len+1);// 外部去釋放,遞歸時可能有泄露
strcat(c, e);
strcat(c, reverse(b));
strcat(c, s);

free(b);
return c;
}

8. 爲何在析構函數中不該該拋出異常?
由於析構函數主要是已經進入清理內存的階段,這時拋出異常的話沒有地方去捕捉,會引發系統異常退出。

9.sprintf,strcpy,memcpy使用上有什麼要注意的地方
strcpy是一個字符串拷貝的函數,它的函數原型爲strcpy(char *dst, const char *src);
src開始的一段字符串拷貝到dst開始的內存中去,結束的標誌符號爲’\0′,因爲拷貝的長度不是由咱們本身控制的,因此這個字符串拷貝很容易出錯。具有字符串拷貝功能的函數有memcpy,這是一個內存拷貝函數,它的函數原型爲memcpy(char *dst, const char* src, unsigned int len);
將長度爲len的一段內存,從src拷貝到dst中去,這個函數的長度可控。可是會有內存疊加的問題。
sprintf是格式化函數。將一段數據經過特定的格式,格式化到一個字符串緩衝區中去。sprintf格式化的函數的長度不可控,有可能格式化後的字符串會超出緩衝區的大小,形成溢出。

10 程序在內存中運行時,內存分幾個區?各自用途?
答:棧區 由編譯器自動分配釋放存放函數的參數值,局部變量的值等。在高級語言中不須要顯式的分配和釋放
堆區 通常由程序員手動分配釋放,若是不釋放可有由OS釋放。
數據區 存儲全局和靜態變量。初始化的全局和靜態變量在一塊區域,未初始化的放在相鄰的一塊區域,程序結束後由系統釋放。
代碼區 存放函數體的二進制代碼。

11 引用與指針有什麼區別?
答:引用是給變量起一個別名 也就是一個變量有兩個名字 他們是同一塊空間
指針是分配一塊內存用來保存變量的地址 間接引用變量

 

ios面試攻略(3.1)  

2013-10-27 11:18:15|  分類: IOS面試 |  標籤:ios面試題目  |舉報|字號 訂閱

 
 
來自: 藍色維度
4、OC相關

1.obj-c有多重繼承麼?不是的話有什麼替代方法? Category是什麼?重寫一個類的方式用繼承好仍是分類好?爲何?
cocoa 中全部的類都是NSObject 的子類。oc不支持多繼承,你不用去考慮繁瑣的多繼承 ,虛基類的概念.
多繼承在這裏是用protocol 委託代理 來實現的
Category是類別,重寫一個類的方法,用繼承仍是分類要根據具體狀況分析。

分類與繼承:
通常狀況用分類好,用Category去重寫類的方法,僅對本Category有效,不會影響到其餘類與原有類的關係。可是若是須要在重寫的時候,還要調用原來的方法,就須要用繼承了。分類是徹底重寫,沒法調用原來的同名方法。

2.obj-c有私有方法麼?私有變量呢 ?
objective-c – 類裏面的方法只有兩種, 靜態方法和實例方法.
可是能夠經過把方法的聲明和定義都放在.m文件中來實現一個表面上的私有方法。
有私有變量,能夠經過@private來修飾,或者把聲明放到.m文件中。
Objective‐C中,全部實例變量默認都是私有的,全部實例方法默認都是公有的

3.#import跟#include的區別? 後面的括號<>與」" 的區別?
#include?可能會重複包含,須要使用#pragram once 或者#ifdef 的方式來避免重複包含
#import沒有這個問題,並且不會引發交叉編譯
<>包含會從系統目錄下開始尋找頭文件
「」包含會優先從當前目錄下尋找頭文件,找不到再去系統目錄下尋找。

4.ObjC中,與alloc語義相反的方法是dealloc仍是release?

retain語義相反的方法是dealloc仍是release,爲何?
須要與alloc配對使用的方法是dealloc仍是release,爲何?
答:alloc與dealloc語意相反,alloc是建立變量,dealloc是釋放變量。
retain 對應release,retain 保留一個對象。調用以後,變量的計數加1。調用release後,變量的引用計數減1,當減爲0時,dealloc方法會自動調用。咱們通常不顯示地調用dealloc這個方法。
alloc 須要與release配對使用,由於alloc 這個函數調用以後,變量的計數加1。因此在調用alloc 以後,必定要調用對應的release。
另外,在release一個變量以後,他的值仍然有效,因此最好是後面緊接着再var = nil。

5.OC中加號方法與減號的區別?
答:加號方法是類方法 屬於靜態方法
減號方法是實例 必須由類的實例來調用

6.常見的object-c的數據類型有那些, 和C的基本數據類型有什麼區別?如:NSInteger和int
object-c的數據類型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,這些都是class,建立後即是對象。
基本類型還有CGFloat,NSInteger等等。這些是爲了之後兼容考慮。如今是32位NSInteger佔4個字節,若是之後cpu升級了,之後int型佔到8位了,不須要修改代碼,還有NSInteger就能夠作到。
C語言的基本數據類型int,只是必定字節的內存空間,用於存放數值;而object-c的NSNumber包含有父類NSObject的方法和NSNumber本身的方法,能夠完成複雜的操做。

:objective-c與C++比較

嵌套調用方法:
objective-c [[[對象 方法1] 方法2] 方法3];函數調用順序,依次由內向外用。
C++ 對象.方法1( ).方法2( ).方法3( );

方法調用形式:
objective-c [ 對象 方法名:參數A 方法名:參數B...];
C++ 對象.方法名(參數列表);
對象的建立:
objective-c 類名 對象指針=[[類名 alloc] 初始化方法];
C++ 類名 對象指針=new 構造方法;

空指針:
objective-c nil // 給空指針發送消息不會崩潰,只是沒反應
C++ NULL //設用空指針的方法會崩潰

 

5、IOS面試之十大問題資深Cocoa開發

如下問題的答案依據本身的經驗整理來,完善中。。。

1.你使用過Objective-C的運行時編程(Runtime Programming)麼?若是使用過,你用它作了什麼?你還能記得你所使用的相關的頭文件或者某些方法的名稱嗎?
答:整個OC都是運行在一套Runtime基礎之上的。不過大部分咱們不直接接觸它的Runtime Programming.
咱們使用下面這些方法時,動態判斷一個對象的類型,是否能對某個方法進行響應等等,都用到了OC的運行時特色。
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
- (BOOL)respondsToSelector:(SEL)aSelector;
運行時的一個頭文件是objc/runtime.h。
咱們能夠利用裏面的一些方法直接發送消息,如objc_msgSend().
也能夠動態的給某個類添加方法,如class_addMethod().
甚至還能夠動態添加一個類,如objc_addClass()。

2.你實現過多線程的Core Data麼?NSPersistentStoreCoordinator,NSManagedObjectContext和NSManagedObject中的哪些須要在線程中建立或者傳遞?你是用什麼樣的策略來實現的?
答:沒弄過。

3.Core開頭的系列的內容。是否使用過CoreAnimation和CoreGraphics。UI框架和CA,CG框架的聯繫是什麼?分別用CA和CG作過些什麼動畫或者圖像上的內容。(有須要的話還能夠涉及Quartz的一些內容)
答:涉及過一些。
UI框架內部仍是由CA和CG實現的。
CA作過一些view的描邊操做,還有淡入淡出的轉場動畫。
CG作過一個畫圖程序,能夠記錄畫筆的位置及線條顏色,能夠合成一個UIImage.

4.是否使用過CoreText或者CoreImage等?若是使用過,請談談你使用CoreText或者CoreImage的體驗。
答:沒弄過。

5.NSNotification和KVO的區別和用法是什麼?何時應該使用通知,何時應該使用KVO,它們的實現上有什麼區別嗎?若是用protocol和delegate(或者delegate的Array)來實現相似的功能可能嗎?若是可能,會有什麼潛在的問題?若是不能,爲何?
KVO只能監測屬性的變化,經過NSString類型的屬性名來實現。可是實現了自動監測,當屬性值變化時,會自動通知觀察者,不用再添加代碼了。
NSNotification比較靈活,能夠監測的內容較多,可是須要被觀察者手動發送通知,觀察者才能響頻。
protocol經過添加一個NSArray也能實現相似的功能,可是實現上須要本身處理delegate的添加與刪除,本身在屬性變化時手動通知,較繁瑣,易出錯。

6.你用過NSOperationQueue麼?若是用過或者瞭解的話,你爲何要使用NSOperationQueue,實現了什麼?請描述它和GCD的區別和相似的地方(提示:能夠從二者的實現機制和適用範圍來描述)。

7.既然提到GCD,那麼問一下在使用GCD以及block時要注意些什麼?它們兩是一回事兒麼?block在ARC中和傳統的MRC中的行爲和用法有沒有什麼區別,須要注意些什麼?

8.您是否作過異步的網絡處理和通信方面的工做?若是有,能具體介紹一些實現策略麼?
作過。
經過註冊代碼或者block的方式,實現回調。在網絡處理方面,統一處理出錯的狀況,沒出錯的狀況下,將數據分別發送給接收者。

9.對於Objective-C,你認爲它最大的優勢和最大的不足是什麼?對於不足之處,如今有沒有可用的方法繞過這些不足來實現需求。若是能夠的話,你有沒有考慮或者實踐太重新實現OC的一些功能,若是有,具體會如何作?
優勢: 與C,C++兼容,不少之前的類庫能夠不用修改直接使用。動態識別,比較靈活。加入類別,擴展方便。
缺點: 不支持重載和多繼承,運行時致使效率稍低。
後面的問題沒考慮那麼多。

10.你實現過一個框架或者庫以供別人使用麼?若是有,請談一談構建框架或者庫時候的經驗;若是沒有,請設想和設計框架的public的API,並指出大概須要如何作、須要注意一些什麼方面,來使別人容易地使用你的框架。
答:曾經移植過一個框架,把C++的一套類庫移植到OC上面,主要工做就是作一個oc++的接口層。作的過程當中,遇到的問題就是在原來框架中,不少頭文件中用結構體或者類的地方,沒有用指針,致使不能用聲明的方式來使用類和結構體,必須在頭文件中把其它頭文件導入,這樣致使整個接口須要提供的頭文件太多了。
還封裝過供他人調用的接口。建議就是調用方法儘量簡單,作好傳入參數的安全檢查及錯誤提醒。由於你沒法肯定你的調用者給你傳什麼樣的數據進來。若是實現方法中耗時較長,須要用異步的方式進行結果返回,能夠選用delegate或者block的方式。

 

6、開發經驗及技巧

1. 下面請求數據用了什麼協議,請求的數據格式是什麼?
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:http://pzpromop.s3.amazonaws.com/PromoNeutral.html]]];
[self.view addSubview:webView];
答:用了http協議,請求的數據格式是html文本。

2. 想傳輸一張圖片,能夠用什麼協議傳輸?
答:http.

3.一個UITableView的實例,從新加載數據的方法是什麼?
答:reloadData從新加載數據源中的所有數據
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
從新加載指定section中的數據
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
從新加載指定行的數據

4.如何對iOS設備進行性能測試?
Profile-> Instruments ->Time Profiler

5. Object C中建立線程的方法是什麼?若是在主線程中執行代碼,方法是什麼?若是想延時執行代碼、方法又是什麼?
答:線程建立有三種方法:使用NSThread建立、使用GCD的dispatch、使用子類化的NSOperation,而後將其加入NSOperationQueue;
在主線程執行代碼,方法是performSelectorOnMainThread,
若是想延時執行代碼能夠用performSelector:onThread:withObject:waitUntilDone:或者dispatch_after或者NSTimer

6.建一個工程用到最基本的兩個框架是什麼?
答:UIKit框架 Foundation框架

7.若是UIView *view 已經實例化 在view 僅添加了N個UIButton類的實例,這些button不是全局的,而且button已經用tag區分開,如何快速找出其中指定的一個button改變它的某個屬性?
答:[view viewWithTag:tagValue];

8.如何將產品進行多語言發佈?
答:開發中xib針對每一個語言作一個。
字符串用NSLocalizedString宏包含起來
Make File Localizable

9.Animation的不一樣形式,並加以代碼示例.
答:枚舉以下:
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
UIViewAnimationOptionLayoutSubviews = 1 << 0,
UIViewAnimationOptionAllowUserInteraction = 1 << 1, // turn on user interaction while animating
UIViewAnimationOptionBeginFromCurrentState = 1 << 2, // start all views from current value, not initial value
UIViewAnimationOptionRepeat = 1 << 3, // repeat animation indefinitely
UIViewAnimationOptionAutoreverse = 1 << 4, // if repeat, run animation back and forth
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5, // ignore nested duration
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6, // ignore nested curve
UIViewAnimationOptionAllowAnimatedContent = 1 << 7, // animate contents (applies to transitions only)
UIViewAnimationOptionShowHideTransitionViews = 1 << 8, // flip to/from hidden state instead of adding/removing

UIViewAnimationOptionCurveEaseInOut = 0 << 16, // default
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,

UIViewAnimationOptionTransitionNone = 0 << 20, // default
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
UIViewAnimationOptionTransitionCurlUp = 3 << 20,
UIViewAnimationOptionTransitionCurlDown = 4 << 20,
UIViewAnimationOptionTransitionCrossDissolve = 5 << 20,
UIViewAnimationOptionTransitionFlipFromTop = 6 << 20,
UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20,
} NS_ENUM_AVAILABLE_IOS(4_0);
感受這個知道怎麼查api就好,用的時候,能夠直接查看頭文件。

閱讀(41)評論(0)
 
 

ios面試攻略(3.2)  

2013-10-27 11:19:06|  分類: IOS面試 |  標籤:ios面試題目  |舉報|字號 訂閱

 
 

來自:藍色維度

 

7、內存管理

1.objc的內存管理簡介
(1)若是您經過分配和初始化(好比[[MyClass alloc] init])的方式來建立對象,您就擁有這個對象,須要負責該對象的釋放。這個規則在使用NSObject的便利方法new 時也一樣適用。
(2)若是您拷貝一個對象,您也擁有拷貝獲得的對象,須要負責該對象的釋放。
(3)若是您保持一個對象,您就部分擁有這個對象,須要在再也不使用時釋放該對象。
(4)經過alloc,new, copy, retain的對象,retainCount+1;release或者autorelease後retainCount-1,若是retainCount爲0時,對象會被消毀,dealloc方法被調用。
(5)誰擁有,誰管理;

2.什麼是retain count?
答:引用計數(ref count或者retain count)。對象的內部保存一個數字,表示被引用的次數。
例如,某個對象被兩個指針所指向(引用)那麼它的retain count爲2。須要銷燬對 象的時候,不直接調用dealloc,而是調用release。release會 讓retain count減1,只有retain count等於0,系統纔會調用dealloc真正銷燬這個對象。

3.自動釋放池是什麼,如何工做?
答:當您向一個對象發送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。它仍然是個正當的對象,所以自動釋放池定義的做用域內的其它對象能夠向它發送消息。當程序執行到做用域結束的位置時,自動釋放池就會被釋放,池中的全部對象也就被釋放。

4.autorelease的對象是在何時被release的?
答:autorelease實際上只是把對release的調用延遲了,對於每個Autorelease,系統只是把該Object放入了當前的Autorelease pool中,當該pool被釋放時,該pool中的全部Object會被調用Release。
對於每個Runloop, 系統會隱式建立一個Autorelease pool,這樣全部的release pool會構成一個象CallStack同樣的一個棧式結構,在每個Runloop結束時,當前棧頂的Autorelease pool會被銷燬,這樣這個pool裏的每一個Object(就是autorelease的對象)會被release。

5.那什麼是一個Runloop呢?
一個UI事件,Timer call, delegate call, 都會是一個新的Runloop。

6.如下每行代碼執行後,person對象的retain count分別是多少
Person *person = [[Person alloc] init]; count 1
[person retain]; count 2
[person release];count 1
[person release];retain count = 1;

7.下面代碼中obj2是否須要dealloc?
ClassA *obj1 = [[ClassA alloc] init];
ClassA *obj2 = obj1;
[obj1 hello]; //輸出hello
[obj1 release];
[obj2 hello]; //程序可否執行到這一行?
[obj2 release];
答 不須要 他和obj2指向的是同一塊空間

8.看下面的程序,第一個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]);
[ary removeAllObjects];
NSLog(@」%@%d」,str,[str retainCount]);
答:
str的retainCount建立+1,retain+1,加入數組自動+1
3
retain+1,release-1,release-1
2
數組刪除全部對象,全部數組內的對象自動-1
1

9.autorelease和垃圾回收機制(gc)有什麼關係?
答:autorelase是用代碼手寫,在eventloop結束後被釋放。
垃圾回收機制開啓的話,你只用alloc,不用release,它會自動偵測一些你不用的對象,將它release掉。
可能在實現方式上或者說release的時機判斷上有不一樣,可是效果都是自動relase這個對象。

10.IPhone OS有沒有垃圾回收(gc)?
沒有。iPhone開發的時候沒有垃圾回收機制,OC支持gc,但只限制在Mac OS上。

11.這段代碼有什麼問題,如何修改
for (int i = 0; i < someLargeNumber; i++)
{
NSString *string = @」Abc」;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@「%@」, string);
}
答:同時生成了大量autorelease對象,不利於內存管理。可是若是放在子線程的話,並且沒有開啓垃圾回收機制的話,則會形成內存泄露。
修改一:
for(int i = 0; i<somelargenumber;i++){
 NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
[pool1 drain];
}
修改二:
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
for(int i = 0; i<somelargenumber;i++){
 NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
}
[pool1 drain];
一點說明:
修改一的autoreleasePool的創建方法是考慮在若是每次循環生成大量的autorelease對象,這些對象佔用很大內存的狀況下,循環了1000次,那麼這些全部的內存加起來就已經夠程序崩潰了,那麼這時候加在循環裏面能夠避免程序崩潰。
可是若是程序循環1000次生成的內存也不是不少,則能夠用方法二,提升效率。
[pool drain][pool release]在沒有垃圾回收機制的狀況下,他們的效果是同樣的。可是若是作mac開發並且開啓了垃圾回收機制的話,要用drain而不是release,由於那種狀況下用release只是把pool這個對象清理了,而pool裏面的對象是沒有被清理掉的

附:CoreFoundation部分
1)create,copy會造成own關係,不須要時應該CFRelease();
2) get方式獲得的object,不造成own關係,不須要管理;
3)一個object做爲參數傳遞到函數中後,receiver不與他造成own關係,也就是可能在任什麼時候間被deallocate掉,因此須要CFRetain();
4)CFIndex count = CFGetRetainCount(obj);
5) myCFObj1 = myCFObj2-->引用拷貝,不會生成2個對象,應該使用CFStringCreatCopy()
6)符合的CF對象,copy時須要本身實現deep copy;

8、CocoaTouch

1.main.m中都發生了什麼?
答:程序入口,建立 自動釋放池,建立應用程序對象,並啓動其主循環,運行程序,釋放程序運行期間得全部加入自動釋放池的對象。

2.int retVal = UIApplicationMain(argc, argv, nil, nil); 是什麼意思?
答:UIApplication對象進行了初始化,這個方法除了argc 和 argv 參數外,另外這個函數還有兩個字符串參數來識別UIApplication類和UIApplication代理類,在這裏默認是2個nil,第一個參數爲nil就默認把UIApplication類做爲缺省值進行初始化,能夠在這裏不填nil而是使用本身定義的UIApplication子類。至於第二個參數nil就設置爲nil就把模板生成的HelloWorldAppdelegate類做爲默認值。

3.編寫NSArray的setter和getter.
答:getter比較容易,直接返回NSArray的指針就能夠了,
setter注意每一個元素加進去得時候須要retain一次。

4.什麼是Notification?答:觀察者模式,controller向defaultNotificationCenter添加本身的notification,其餘類註冊這個notification就能夠收到通知,這些類能夠在收到通知時作本身的操做(多觀察者默認隨機順序發通知給觀察者們,並且每一個觀察者都要等當前的某個觀察者的操做作完才能輪到他來操做,可用NotificationQueue的方式安排觀察者的反應順序,也能夠在添加觀察者中設定反映時間,取消觀察須要在viewDidUnload 跟dealloc中都要註銷)

5.多線程編程中,NSThread子線程與主線程的交互.
答:子線程內執行[self performSelectorOnMainThread:@selector(function:)withObject:];通知主線程執行相應方法。或者用全局變量的方式。

6.objective-c中是全部對象間的交互是如何實現的?(深圳皆凱科技有限公司筆試題)
答:在Objective-C中全部對象間的交互都是經過指針實現的,確切的說話,叫作發送消息。

8.objective-c中是如何實現線程同步的?
答:關鍵字@synchronized()

7.id 聲明的對象有什麼特性?
答:id 聲明的對象具備運行時的特性,便可以指向任意類型的objcetive-c的對象;

8.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
網絡/li>
Bonjour
WebKit
BSD Sockets
用戶應用
Address Book
Core Location
Map Kit
Store Kit

 

9、設計模式

1.MVC模式的理解
MVC設計模式考慮三種對象:模型對象、視圖對象、和控制器對象。模型對象表明特別的知識和專業技能,它們負責保有應用程序的數據和定義操做數據的邏輯。視圖對象知道如何顯示應用程序的模型數據,並且可能容許用戶對其進行編輯。控制器對象是應用程序的視圖對象和模型對象之間的協調者。

2.描述一下iOS SDK中如何實現MVC的開發模式
MVC是模型、視圖、控制開發模式,對於iOS SDK,全部的View都是視圖層的,它應該獨立於模型層,由視圖控制層來控制。全部的用戶數據都是模型層,它應該獨立於視圖。全部的ViewController都是控制層,由它負責控制視圖,訪問模型數據。

3.類工廠方法是什麼
類工廠方法的實現是爲了向客戶提供方便,它們將分配和初始化合在一個步驟中,返回被建立的對象,並進行自動釋放處理。這些方法的形式是+ (type)className…(其中 className不包括任何前綴)。
工廠方法可能不只僅爲了方便使用。它們不但能夠將分配和初始化合在一塊兒,還能夠爲初始化過程提供對象的分配信息。
類工廠方法的另外一個目的是使類(好比NSWorkspace)提供單件實例。雖然init…方法能夠確認一個類在每次程序運行過程只存在一個實例,但它須要首先分配一個「生的」實例,而後還必須釋放該實例。
工廠方法則能夠避免爲可能沒有用的對象盲目分配內存。

4.單件實例是什麼
Foundation 和 Application Kit 框架中的一些類只容許建立單件對象,即這些類在當前進程中的惟一實例。舉例來講,NSFileManager 和NSWorkspace 類在使用時都是基於進程進行單件對象的實例化。當向這些類請求實例的時候,它們會向您傳遞單一實例的一個引用,若是該實例還不存在,則首先進行實例的分配和初始化。單件對象充當控制中心的角色,負責指引或協調類的各類服務。若是類在概念上只有一個實例(好比
NSWorkspace),就應該產生一個單件實例,而不是多個實例;若是未來某一天可能有多個實例,您能夠使用單件實例機制,而不是工廠方法或函數。

 

10、操做系統

1.線程與進程的區別和聯繫?
答:進程和線程都是由操做系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。
進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。

2.列舉幾種進程的同步機制,並比較其優缺點。
答案: 原子操做 信號量機制 自旋鎖 管程,會合,分佈式系統
進程之間通訊的途徑
答案:共享存儲系統消息傳遞系統管道:以文件系統爲基礎
進程死鎖的緣由
答案:資源競爭及進程推動順序非法
死鎖的4個必要條件
答案:互斥、請求保持、不可剝奪、環路
死鎖的處理
答案:鴕鳥策略、預防策略、避免策略、檢測與解除死鎖

3.堆和棧的區別
管理方式:對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來講,釋放工做由程序員控制,容易產生memory leak。
申請大小:
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就肯定的常數),若是申請的空間超過棧的剩餘空間時,將提示overflow。所以,能從棧得到的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是因爲系統是用鏈表來存儲的空閒內存地址的,天然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。
碎片問題:對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降。對於棧來說,則不會存在這個問題,由於棧是先進後出的隊列,他們是如此的一一對應,以致於永遠都不可能有一個內存塊從棧中間彈出
分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,好比局部變量的分配。動態分配由alloca函數進行分配,可是棧的動態分配和堆是不一樣的,他的動態分配是由編譯器進行釋放,無需咱們手工實現。
分配效率:棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的。

 

11、雜項

1.動態綁定
—在運行時肯定要調用的方法
動態綁定將調用方法的肯定也推遲到運行時。在編譯時,方法的調用並不和代碼綁定在一塊兒,只有在消實發送出來以後,才肯定被調用的代碼。經過動態類型和動態綁定技術,您的代碼每次執行均可以獲得不一樣的結果。運行時因子負責肯定消息的接收者和被調用的方法。運行時的消息分發機制爲動態綁定提供支持。當您向一個動態類型肯定了的對象發送消息時,運行環境系統會經過接收者的isa指針定位對象的類,並以此爲起點肯定被調用的方法,方法和消息是動態綁定的。並且,您沒必要在Objective-C 代碼中作任何工做,就能夠自動獲取動態綁定的好處。您在每次發送消息時,
特別是當消息的接收者是動態類型已經肯定的對象時,動態綁定就會例行而透明地發生。

2.目標-動做機制
目標是動做消息的接收者。一個控件,或者更爲常見的是它的單元,以插座變量(參見」插座變量」部分)的形式保有其動做消息的目標。
動做是控件發送給目標的消息,或者從目標的角度看,它是目標爲了響應動做而實現的方法。
程序須要某些機制來進行事件和指令的翻譯。這個機制就是目標-動做機制。

3.什麼是鍵-值,鍵路徑是什麼
模型的性質是經過一個簡單的鍵(一般是個字符串)來指定的。視圖和控制器經過鍵來查找相應的屬性值。在一個給定的實體中,同一個屬性的全部值具備相同的數據類型。鍵-值編碼技術用於進行這樣的查找—它是一種間接訪問對象屬性的機制。
鍵路徑是一個由用點做分隔符的鍵組成的字符串,用於指定一個鏈接在一塊兒的對象性質序列。第一個鍵的性質是由先前的性質決定的,接下來每一個鍵的值也是相對於其前面的性質。鍵路徑使您能夠以獨立於模型實現的方式指定相關對象的性質。經過鍵路徑,您能夠指定對象圖中的一個任意深度的路徑,使其指向相關對象的特定屬性。

4.何時用delegate,何時用Notification?
答:delegate針對one-to-one關係,而且reciever能夠返回值給sender,
notification 能夠針對one-to-one/many/none,reciever沒法返回值給sender.
因此,delegate用於sender但願接受到reciever的某個功能反饋值,notification用於通知多個object某個事件。

5.什麼是KVC和KVO?
答:KVC(Key-Value-Coding)內部的實現:一個對象在調用setValue的時候,(1)首先根據方法名找到運行方法的時候所須要的環境參數。(2)他會從本身isa指針結合環境參數,找到具體的方法實現的接口。(3)再直接查找得來的具體的方法實現。
KVO(Key-Value-Observing):當觀察者爲一個對象的屬性進行了註冊,被觀察對象的isa指針被修改的時候,isa指針就會指向一箇中間類,而不是真實的類。因此isa指針其實不須要指向實例對象真實的類。因此咱們的程序最好不要依賴於isa指針。在調用類的方法的時候,最好要明確對象實例的類名。
其它回答:
kvc就是key value coding,簡而言之就是根據key值改變它的內容,我以爲很相似於dictionary。
kvo就是Key Value Observing,就是至關於你監控特定對象的特定key,當key對應的值發生改變時,會觸發它的對應方法。
kvc實現(NSKeyValueCoding Protocol),最簡單的方法就是setValue: forKey: 以及valueForKey:方法。例如你實現一個Person類,有兩個property name,age,生成一個新對象p,能夠用[p setValue:@"Solomon" forKey:@"name"];這樣的方法進行賦值。
kvo實現(NSKeyValueObserving Protocol),–addObserver:forKeyPath:options:context:對你想要監控的對象,想要監控的屬性添加一個observe,當值改變時,會觸發– willChangeValueForKey:等方法。
kvc kvo結合使用,能夠看成對對象屬性值進行監控的一個notification,它對值進行監控。而notification也同時能夠對消息響應之類 作出監控。
簡單說KVC就是一個實現並擴展了setter/getter的方法集。

6.Notification和KVO有什麼不一樣?
KVO就是給屬性添加一個監控器,當值發生改變的時候,給你一個接口去處理它。textView用過吧,當textView的值改變時,不也有一個textViewDidChange:的delegate方法麼?
它就是一個NSObject的protocol,原本就是一個很簡單的東西,不要想的很複雜化。這些東西的提出只是爲了更方便,而不是它有什麼特殊的含義,正如MVC同樣。
notification也就是在程序檢測event的loop裏面加上一個跟蹤事件的判斷,若是接收到了這個事件,則作本身想要去作的事情。好比一個uiview的對象接收到一個觸摸事件,它在系統檢測event的無限循環裏接收到了它,而後返回一個uitouch的事件讓你去處理,從根本上來講它和notification的性質同樣的,雖然可能實現方式不盡相同,可是總歸是跳不出這個圈子的。
固然,再往底層的東西,怎麼去傳遞notification之類,蘋果封裝好了,你也不可能知道。就算你是蘋果的程序員,由你來實現,也可能有不一樣的方式來達到一樣的目的。而這個已經超出了sdk編程的範圍。

 
 
 
 
 
閱讀(203)評論(0)
相關文章
相關標籤/搜索