iOS精典面試(二)

說說你對 OC 中 load 方法和 initialize 方法的異同。——主要說一下執(zhí)行時間,各自用途,沒實現(xiàn)子類的方法會不會調(diào)用父類的?
說說你對 block 的理解。—— 三種 block,棧上的自動復(fù)制到堆上,block 的屬性修飾符是 copy,循環(huán)引用的原理和解決方案。
說說你對 runtime 的理解。——主要是方法調(diào)用時如何查找緩存,如何找到方法,找不到方法時怎么轉(zhuǎn)發(fā),對象的內(nèi)存布局。

提高方法查找機制效率-Class Cache
通過上文我們知道,在OC中,方法是通過isa指針,查找Class中的Method list來查詢的。而一個類往往會實現(xiàn)很多方法,每次調(diào)用都查詢一次Method list的分發(fā)表(dispatch table)的代價是很高的(因為,這種查詢可能每個RunLoop就執(zhí)行上億次)。這也就引入了Class Cache.
Class Cache認為,當一個方法被調(diào)用,那么它之后被調(diào)用的可能性比較大。

舉個例子,我們常見的alloc,init,調(diào)用順序如下
 CustomObject * obj = [[CustomObject alloc] init];

alloc是類方法,沿著isa找到CustomObject類元對象,發(fā)現(xiàn)沒有實現(xiàn)alloc
沿著super,找到NSObject類元方法,執(zhí)行alloc方法,并把alloc加入到NSObject類元對象的Class Cache中
init是實例方法,沿著isa找到CustomObject的類對象,發(fā)現(xiàn)沒有實現(xiàn)init
沿著super,找到NSObject類對象,執(zhí)行init,并把init加入到NSObject的類對象Class Cache中

這里,再提一下alloc,init兩個方法
alloc方法的文檔
初始化isa,其他所有屬性被設(shè)為0

init
NSObject的init返回self,其余的子類要調(diào)用[super init]進行必要的初始化工作。

為什么要放在一起寫?
因為alloc和init有可能返回不同的對象

    id a = [NSMutableArray alloc];
    id b = [a init];
    NSLog(@"%p",a);
    NSLog(@"%p",b);
輸出
0x7fc550400fb0
0x7fc5505523a0
  1. 方法的selector
    這兩個參數(shù)為方法的實現(xiàn)提供了調(diào)用者的信息。之所以說是隱藏的,是因為它們在定義方法的源代碼中沒有聲明。它們是在編譯期被插入實現(xiàn)代碼的。
    雖然這些參數(shù)沒有顯示聲明,但在代碼中仍然可以引用它們。我們可以使用self來引用接收者對象,使用_cmd來引用選擇器。如下代碼所示:
- strange
{
    id  target = getTheReceiver();
    SEL method = getTheMethod();
 
    if ( target == self || method == _cmd )
        return nil;
    return [target performSelector:method];
}

當然,這兩個參數(shù)我們用得比較多的是self,_cmd在實際中用得比較少。
獲取方法地址
Runtime中方法的動態(tài)綁定讓我們寫代碼時更具靈活性,如我們可以把消息轉(zhuǎn)發(fā)給我們想要的對象,或者隨意交換一個方法的實現(xiàn)等。不過靈活性的提 升也帶來了性能上的一些損耗。畢竟我們需要去查找方法的實現(xiàn),而不像函數(shù)調(diào)用來得那么直接。當然,方法的緩存一定程度上解決了這一問題。
我們上面提到過,如果想要避開這種動態(tài)綁定方式,我們可以獲取方法實現(xiàn)的地址,然后像調(diào)用函數(shù)一樣來直接調(diào)用它。特別是當我們需要在一個循環(huán)內(nèi)頻繁地調(diào)用一個特定的方法時,通過這種方式可以提高程序的性能。
NSObject類提供了methodForSelector:方法,讓我們可以獲取到方法的指針,然后通過這個指針來調(diào)用實現(xiàn)代碼。我們需要將methodForSelector:返回的指針轉(zhuǎn)換為合適的函數(shù)類型,函數(shù)參數(shù)和返回值都需要匹配上。
我們通過以下代碼來看看methodForSelector:的使用:


void (*setter)(id, SEL, BOOL);
int i;
 
setter = (void (*)(id, SEL, BOOL))[target
    methodForSelector:@selector(setFilled:)];
for ( i = 0 ; i < 1000 ; i++ )
    setter(targetList[i], @selector(setFilled:), YES);

這里需要注意的就是函數(shù)指針的前兩個參數(shù)必須是id和SEL。

當然這種方式只適合于在類似于for循環(huán)這種情況下頻繁調(diào)用同一方法,以提高性能的情況。另外,methodForSelector:是由Cocoa運行時提供的;它不是Objective-C語言的特性。
消息轉(zhuǎn)發(fā)
當一個對象能接收一個消息時,就會走正常的方法調(diào)用流程。但如果一個對象無法接收指定消息時,又會發(fā)生什么事呢?默認情況下,如果是以 [object message]的方式調(diào)用方法,如果object無法響應(yīng)message消息時,編譯器會報錯。但如果是以perform…的形式來調(diào)用,則需要等到運 行時才能確定object是否能接收message消息。如果不能,則程序崩潰。
通常,當我們不能確定一個對象是否能接收某個消息時,會先調(diào)用respondsToSelector:來判斷一下。如下代碼所示:


if ([self respondsToSelector:@selector(method)]) {
    [self performSelector:@selector(method)];
}

不過,我們這邊想討論下不使用respondsToSelector:判斷的情況。這才是我們這一節(jié)的重點。
當一個對象無法接收某一消息時,就會啟動所謂”消息轉(zhuǎn)發(fā)(message forwarding)“機制,通過這一機制,我們可以告訴對象如何處理未知的消息。默認情況下,對象接收到未知的消息,會導(dǎo)致程序崩潰,通過控制臺,我們可以看到以下異常信息:


-[SUTRuntimeMethod method]: unrecognized selector sent to instance 0x100111940
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SUTRuntimeMethod method]: unrecognized selector sent to instance 0x100111940'

這段異常信息實際上是由NSObject的”doesNotRecognizeSelector”方法拋出的。不過,我們可以采取一些措施,讓我們的程序執(zhí)行特定的邏輯,而避免程序的崩潰。

消息轉(zhuǎn)發(fā)機制基本上分為三個步驟:

  1. 動態(tài)方法解析
  2. 備用接收者
  3. 完整轉(zhuǎn)發(fā)
    下面我們詳細討論一下這三個步驟。
    動態(tài)方法解析
    對象在接收到未知的消息時,首先會調(diào)用所屬類的類方法+resolveInstanceMethod:(實例方法)或 者+resolveClassMethod:(類方法)。在這個方法中,我們有機會為該未知消息新增一個”處理方法”“。不過使用該方法的前提是我們已經(jīng) 實現(xiàn)了該”處理方法”,只需要在運行時通過class_addMethod函數(shù)動態(tài)添加到類里面就可以了。如下代碼所示:
void functionForMethod1(id self, SEL _cmd) {
   NSLog(@"%@, %p", self, _cmd);
}
 
+ (BOOL)resolveInstanceMethod:(SEL)sel {
 
    NSString *selectorString = NSStringFromSelector(sel);
 
    if ([selectorString isEqualToString:@"method1"]) {
        class_addMethod(self.class, @selector(method1), (IMP)functionForMethod1, "@:");
    }
 
    return [super resolveInstanceMethod:sel];
}

不過這種方案更多的是為了實現(xiàn)@dynamic屬性。
備用接收者
如果在上一步無法處理消息,則Runtime會繼續(xù)調(diào)以下方法:

- (id)forwardingTargetForSelector:(SEL)aSelector

如果一個對象實現(xiàn)了這個方法,并返回一個非nil的結(jié)果,則這個對象會作為消息的新接收者,且消息會被分發(fā)到這個對象。當然這個對象不能是self自身,否則就是出現(xiàn)無限循環(huán)。當然,如果我們沒有指定相應(yīng)的對象來處理aSelector,則應(yīng)該調(diào)用父類的實現(xiàn)來返回結(jié)果。
使用這個方法通常是在對象內(nèi)部,可能還有一系列其它對象能處理該消息,我們便可借這些對象來處理消息并返回,這樣在對象外部看來,還是由該對象親自處理了這一消息。如下代碼所示:


@interface SUTRuntimeMethodHelper : NSObject
 
- (void)method2;
 
@end
 
@implementation SUTRuntimeMethodHelper
 
- (void)method2 {
    NSLog(@"%@, %p", self, _cmd);
}
 
@end
 
#pragma mark -
 
@interface SUTRuntimeMethod () {
    SUTRuntimeMethodHelper *_helper;
}
 
@end
 
@implementation SUTRuntimeMethod
 
+ (instancetype)object {
    return [[self alloc] init];
}
 
- (instancetype)init {
    self = [super init];
    if (self != nil) {
        _helper = [[SUTRuntimeMethodHelper alloc] init];
    }
 
    return self;
}
 
- (void)test {
    [self performSelector:@selector(method2)];
}
 
- (id)forwardingTargetForSelector:(SEL)aSelector {
 
    NSLog(@"forwardingTargetForSelector");
 
    NSString *selectorString = NSStringFromSelector(aSelector);
 
    // 將消息轉(zhuǎn)發(fā)給_helper來處理
    if ([selectorString isEqualToString:@"method2"]) {
        return _helper;
    }
 
    return [super forwardingTargetForSelector:aSelector];
}
 
@end

這一步合適于我們只想將消息轉(zhuǎn)發(fā)到另一個能處理該消息的對象上。但這一步無法對消息進行處理,如操作消息的參數(shù)和返回值。
完整消息轉(zhuǎn)發(fā)
如果在上一步還不能處理未知消息,則唯一能做的就是啟用完整的消息轉(zhuǎn)發(fā)機制了。此時會調(diào)用以下方法:

- (void)forwardInvocation:(NSInvocation *)anInvocation

運行時系統(tǒng)會在這一步給消息接收者最后一次機會將消息轉(zhuǎn)發(fā)給其它對象。對象會創(chuàng)建一個表示消息的NSInvocation對象,把與尚未處理的消息 有關(guān)的全部細節(jié)都封裝在anInvocation中,包括selector,目標(target)和參數(shù)。我們可以在forwardInvocation 方法中選擇將消息轉(zhuǎn)發(fā)給其它對象。

//內(nèi)存布局
http://blog.csdn.net/cx_wzp/article/details/50905708

說說你對 MVC 和 MVVM 的理解。—— MVC 的 C 太臃腫,可以和 V 合并,變成 MVVM 中的 V,而 VM 用來將 M 轉(zhuǎn)化成 V 能用的數(shù)據(jù)。
說說 UITableView 的調(diào)優(yōu)。——一方面是通過 instruments 檢查影響性能的地方,另一方面是估算高度并在 runloop 空閑時緩存。
談?wù)勀銓?ARC 的理解。ARC 是編譯器完成的,依靠引用計數(shù),談?wù)剮讉€屬性修飾符的內(nèi)存管理策略,什么情況下會內(nèi)存泄露

7、層和UIView的區(qū)別是什么?
答:兩者最大的區(qū)別是,圖層不會直接渲染到屏幕上,UIView是iOS系統(tǒng)中界面元素的基礎(chǔ),所有的界面元素都是繼承自它。它本身完全是由CoreAnimation來實現(xiàn)的。它真正的繪圖部分,是由一個CALayer類來管理。UIView本身更像是一個CALayer的管理器。一個UIView上可以有n個CALayer,每個layer顯示一種東西,增強UIView的展現(xiàn)能力。

3、垃圾回收和引用計數(shù)的區(qū)別?引用計數(shù)為0了才釋放
2、自動釋放池的作用?
autorelease的使用
自動釋放池:是用來自動釋放對象的,不需要關(guān)心對象釋放的時間,不需要關(guān)心對象什么時候調(diào)用release
自動釋放池釋放的時間:自動釋放池結(jié)束
自動釋放池原理:當池子結(jié)束,會想池子里面的對象發(fā)送一條release消息
自動釋放池使用:1.創(chuàng)建對象 2.加入自動釋放池
兩種使用方式:

①Person *p = [Person new];
 [p autorelease];        
②Person *p1 = [[Person new]autorelease];

注意事項:
1.并不是放到自動釋放池中的代碼中,就會自動加入到自動釋放池的
需要我們調(diào)用autorelease方法的
在自動釋放池的外部調(diào)用autorelease方法,是不會被加入到自動釋放池中的
不管這個對象是在自動釋放池內(nèi)部還是外部創(chuàng)建的,只要在這個對象在自動釋放池中調(diào)用autorelease方法,那么就會被放到自動釋放池中
總結(jié):不管是在什么地方創(chuàng)建的對象,都必須在自動釋放池中,調(diào)用autorelease方法,才會被加入自動釋放池中
2.自動釋放池的嵌套使用:自動釋放池是個棧結(jié)構(gòu),先進后出(每個自動釋放池就當成一個桶,先放到下面的,最后拿出來,有利于理解)
延遲調(diào)用release,在自動釋放池結(jié)束時,讓對象調(diào)用release
注意:自動釋放池可不是直接釋放對象,而只是讓對象release一次,如果對象的retainCount為2,那么自動釋放池只能讓retainCount變?yōu)?,對象就銷毀不了

3.自動釋放池中不適合放占用內(nèi)存比較大的對象
1)這是種延遲釋放機制,是直到自動釋放池結(jié)束才釋放的,中間大內(nèi)存文件一直在占用內(nèi)存
2)不要把大量循環(huán)操作放到同一個@autoreleasepool(自動釋放池)之間,這樣會造成內(nèi)存峰值的
4.錯誤用法:
1)連續(xù)調(diào)用多次autorelease,釋放池結(jié)束時會執(zhí)行兩次release
? 注意:一個retainCount為1的對象,如果release兩次,程序是會崩潰的
· 2)alloc之后調(diào)用了autorelease,之后又調(diào)用了release(還是release兩次)
5.autorelease的應(yīng)用場景:
經(jīng)常用來在類方法中,快速創(chuàng)建一個對象
我們平常定義一個指針,先alloc,再init,最后還要手動釋放,太麻煩,索性直接當定義出來的同時,調(diào)用一下autorelease方法,當自動釋放池結(jié)束的時候,自動就release,通常可以用于重寫init的時候,直接放在init里
【小結(jié)】:
1:自動釋放池的數(shù)據(jù)結(jié)構(gòu)
自動釋放池是以棧的形式實現(xiàn),當你創(chuàng)建一個新的自動釋放池,它將會被添加到棧頂。接受autorelease
消息的對象將會唄放入棧頂
2:如何持有對象
當我們使用alloc,copy,retain對象獲取一個對象時,我們需要負責顯示的安排對象的銷毀,其他方法獲取的
的對象將交給自動釋放池進行釋放(單例模式除外)
3:release和drain的區(qū)別
當我們向自動釋放池pool發(fā)送release消息,將會向池中臨時對象發(fā)送一條release消息,并且自身也會唄銷毀。
向它發(fā)送drain消息時,只會指定前者。

1.Objective-C可以實現(xiàn)多繼承嗎?可以實現(xiàn)多個接口嗎?Category是什么?重寫一個類的方式是用繼承好還是用分類好?為什么?
2.OC使用協(xié)議實現(xiàn)多繼承,可以遵守多個協(xié)議實現(xiàn)多接口。category是OC中的類別,類別是用于給一個現(xiàn)有類添加新方法。重寫類一般采用繼承的方式,分類(類別)在給以個類添加同名方法后,會造成原有類中方法的實效,而繼承重寫的方法,依然可以在使用父類對象調(diào)用該方法。
3.定義屬性的時候,什么時候使用retain/copy/assign?寫一個setter方法,用于完成@property(nonatomic,retain) NSString* name;寫一個setter方法,用于完成@property(nonatomic,copy)NSString* name;
retain用于保留對象的引用計數(shù),在使用retain聲明的屬性做賦值的時候,成員變量指針會保留被賦值對象的引用計數(shù)。
copy聲明的屬性,在使用屬性賦值的時候會,成員指針會指向新副本,這個副本是一個不可變副本,不論賦值對象是不是可變的。
assign用于基本數(shù)據(jù)類型的屬性聲明,不涉及到內(nèi)存管理的問題,也是缺省參數(shù)
retain聲明的屬性的setter方法展開

- (void)setName:(NSString*)name
{
if(_name != name)
{
[_namerelease];
_name= [name retain];
}
}
copy聲明的屬性的setter方法展開
- (void)setName:(NSString*)name
{
if(_name != name)
{
[_namerelease];
_name= [name copy];
}
}

4.什么時候使用NSMutableArray/什么時候使用NSArray
NSMutableArray一般在需要隨時更改數(shù)組結(jié)構(gòu)的時候使用
NSArray一般用于保存一些不需要修改邏輯的數(shù)據(jù)
5.實現(xiàn)字符串“I LOVE CHINA”反串成“CHINA LOVE I”

  1. pch文件的作用
    .pch表示"precompiled header",這是一個你工程要用到的來自于外部框架的頭文件列表。xcode將編譯這些頭到文件,這將減少你在選擇Build或Build and Go時編譯項目的時間。通常用到的頭文件已經(jīng)自動包含了pch,系統(tǒng)編譯每個cpp文件前,都會先include這個文件。這樣就節(jié)省了添加include的時間,相當于加速編譯
    還有就是可以再這里面放入宏,在整個工程中都可以用
    7.怎樣解決重復(fù)編譯

ifndef _DEBUG

ifdef USE_MYLIB

................

endif

  1. awakeFromNib與viewDidLoad區(qū)別
    awakeFromNib
    當.nib文件被加載的時候,會發(fā)送一個awakeFromNib的消息到.nib文件中的每個對象,每個對象都可以定義自己的awakeFromNib函數(shù)來響應(yīng)這個消息,執(zhí)行一些必要的操作。也就是說通過nib文件創(chuàng)建view對象是執(zhí)行awakeFromNib。
    viewDidLoad
    當view對象被加載到內(nèi)存是就會執(zhí)行viewDidLoad,所以不管通過nib文件還是代碼的方式創(chuàng)建對象都會執(zhí)行viewDidLoad。
  2. LayoutSubviews何時會被調(diào)用
    當要調(diào)整subViews時候,需要重寫layoutSubviews方法。
    1:初始化init方法時候不會觸發(fā)。
    2:滾動UIScrollView時會觸發(fā)
    3:旋轉(zhuǎn)UIScreen時會觸發(fā)
    4:當改變view的值時候會觸發(fā),前提是frame前后值發(fā)生了變化
    5:當改變UIview的大小時候會觸發(fā)
  3. public/private/protected的具體區(qū)別
    public公共,加上這個修飾的類或?qū)傩裕梢栽谕粋€包或者別的包里面訪問
    private私有的,加上這個修飾的類或?qū)傩裕荒茉谕惱镌L問,同包和別的包不能訪問
    protected保護,加上這個修飾的類或?qū)傩裕荒茉陬惡屯L問,別的包不能訪問
  4. ARC是什么
    ARC是iOS 5推出的新功能,全稱叫ARC(Automatic Reference Counting)。簡單地說,就是代碼中自動加入了retain/release,原先需要手動添加的用來處理內(nèi)存管理的引用計數(shù)的代碼可以自動地由編譯器完成了。
    該機能在iOS 5/ Mac OS X 10.7開始導(dǎo)入,利用Xcode4.2可以使用該機能。簡單地理解ARC,就是通過指定的語法,讓編譯器(LLVM
    3.0)在編譯代碼時,自動生成實例的引用計數(shù)管理部分代碼。有一點,ARC并不是GC,它只是一種代碼靜態(tài)分析(Static
    Analyzer)工具。
    12.寫一個“標準”宏,這個宏輸入兩個參數(shù)并返回較小的

define MIN(X,Y)((X)>(Y)?(Y):(X))

13.Objective-c中有多重繼承么?不是的話有聲明替代方式?
沒有多繼承,可以通過協(xié)議模擬多繼承
14.Objective-c中有私有方法嗎?私有變量呢?
沒有私有方法,但可以將方法直接實現(xiàn)在.m文件中不在.h文件中聲明時,外部也不能訪問。
有私有變量
15.iPhone OS中有沒有垃圾回收?
沒有
16.常見的object-c的數(shù)據(jù)類型有哪些,和c的基本類型有什么區(qū)別
答:常見的object-c的數(shù)據(jù)類型有NSInteger、CGFloat、NSString、NSNumber、NSArray、NSData,NSInteger會根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是Long,
CGFloat會根據(jù)系統(tǒng)是32位還是64位來決定是本身是float還是double,NSString、NSNumber、NSArray、NSData都是指針類型的對象,在堆中分配空間,而c語言中的char,[]等都是在棧中分配空間
17.id聲明的對象有什么特性?
id聲明的對象具有運行時的特性,即可以指向任意類型的objcetive-c的對象;
18.想nil對象發(fā)送消息會發(fā)生什么?
答:在Objective-C中向nil發(fā)送消息是完全有效的,只是在運行時不會有任何作用。
19.什么是block?block實現(xiàn)原理?
答:block是一個特殊的OC對象,它建立在棧上,而不是堆上,這么做一個是為性能考慮,還有就是方便訪問局部變量。默認情況下block使用到的局部變量都會被復(fù)制,而不是保留。所以它無法改變局部變量的值。如果在變量面前加上__block,那么編譯器回去不會復(fù)制變量,而是去找變量的地址,通過地址來訪問變量,實際上就是直接操作變量。另外block是在棧上分配的,所以一旦離開作用域,就會釋放,因此如果你要把快用在別的地方,必須要復(fù)制一份。block是不能保留的,
retain對塊沒有意義。
20.C++和OC,JAVA和OC之間的區(qū)別?
C++是功能強大,豐富的面向?qū)ο缶幊陶Z言,具有私有、公有、保護權(quán)限的三種成員變量和成員方法,具有私有、公有、保護三種繼承方式,具有重寫,重載,虛函數(shù),虛基類等多態(tài)方式,通過虛基類實現(xiàn)代理回調(diào)。自定義類可以沒有父類。另外具備向量,模板,友元,重載運算符等多種獨特語法
Obj-C是針對mac OS和iOS設(shè)備應(yīng)用程序開發(fā)的專屬編程語言,采用動態(tài)繼承,消息方法機制,沒有真正的重寫機制,沒有私有方法,繼承方式為公有,具備協(xié)議,類別,Block等獨有的語法,萬用父類為NSObject
JAVA是老牌的面向?qū)ο笳Z言,編寫的程序在JAVA虛擬機上運行,真正實現(xiàn)了一次編譯到處運行,具有復(fù)雜的內(nèi)存回收機制,單繼承模式,接口語法類似Obj-C的協(xié)議
21.抽象與接口的區(qū)別?
聲明方法的存在而不去實現(xiàn)它的類被叫做抽象類(abstract class),它用于要創(chuàng)建一個體現(xiàn)某些基本行為的類,并為該類聲明方法,但不能在該類中實現(xiàn)該類的情況。不能創(chuàng)建abstract類的實例。然而可以創(chuàng)建一個變量,其類型是一個抽象類,并讓它指向具體子類的一個實例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。Abstract類的子類為它們父類中的所有抽象方法提供實現(xiàn),否則它們也是抽象類為。取而代之,在子類中實現(xiàn)該方法。知道其行為的其它類可以在類中實現(xiàn)這些方法。
接口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個有程序體。接口只可以定義static
final成員變量。接口的實現(xiàn)與子類相似,除了該實現(xiàn)類不能從接口定義中繼承行為。當類實現(xiàn)特殊接口時,它定義(即將程序體給予)所有這種接口的方法。然后,它可以在實現(xiàn)了該接口的類的任何對象上調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到接口類型或從接口類型轉(zhuǎn)換,instanceof運算符可以用來決定某對象的類是否實現(xiàn)了接口。
22.nil與NULL的區(qū)別?
從Objective-C語言的官方說法上看,nil表示指向?qū)ο蟮闹羔樇此^對象的引用為空,NULL表示指向基礎(chǔ)類型變量即C語言變量的指針為空。如果在非ARC程序的編寫過程中,兩個空是可以互換的,但是在ARC環(huán)境下,普通指針和對象引用被嚴格限制,不能交換使用,因此也應(yīng)盡量不互換使用nil與NULL

  1. BOOL與bool的區(qū)別?
    bool是C語言C99標準中增添的變量類型,Object-C僅僅是從C語言繼承了這種類型,該類型有true和false兩個值,表示真和假。BOOL是Obj-C獨有的布爾類型,有YES和NO兩個值,分別是1和0的宏。Obj-C中同時認為所有非0的值都是真值,0為假值
    24.OC如何實現(xiàn)私有方法?
    Obj-C語法中并沒有私有方法的概念,但是由于Obj-C是通過導(dǎo)入其他類的頭文件來獲取其他類所擁有的成員方法的聲明,因此可以采用編寫方法時,不聲明,或僅在.m文件中的匿名類別中聲明的方式,使方法對外不可見,即可達到方法私有化的目的。但是外部類仍然可以通過@selector來訪問確實存在的私有方法,因此嚴格來講Obj-C確實不能真正實現(xiàn)方法私有化
    25.#import和#include的區(qū)別@ class代表什么
    預(yù)編譯指令
    Objective-C:#import
    C,C++:#include

import由gcc編譯器支持

在Objective-C中,#import被當成#include指令的改良版本來使用。除此之外,#import確定一個文件只能被導(dǎo)入一次,這使你在遞歸包含中不會出現(xiàn)問題。
使用哪一個還是由你來決定。一般來說,在導(dǎo)入Objective-C頭文件的時候使用#import,包含C頭文件時使用#include。比如:

import

include

include

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

二、@class是用來做類引用的
@class就是告訴編譯器有這么一個類,至于類的定義是啥不知道
@class一般用于頭文件中需要聲明該類的某個實例變量的時候用到,在m文件中還是需要使用#import

  1. NSString和NSMutableString的區(qū)別
    NSString是一個不可變的字符串對象。這不是表示這個對象聲明的變量的值不可變,而是表示它初始化以后,你不能改變該變量所分配的內(nèi)存中的值,但你可以重新分配該變量所處的內(nèi)存空間。而NSMutableString是可變的,意味著你可以追加它的內(nèi)存空間,或者修改它所分配的內(nèi)存空間中的值。
    27..關(guān)于語句NSString * str= [NSData alloc]init,編譯和運行分別str代表什么對象?
    首先,聲明NSString str是告訴編譯器,str是一個指向某個Objective-C對象的指針。因為不管指向的是什么類型的對象,一個指針所占的內(nèi)存空間都是固定的,所以這里聲明成任何類型的對象,最終生成的可執(zhí)行代碼都是沒有區(qū)別的。這里限定了NSString只不過是告訴編譯器,請把str當做一個NSString來檢查,如果后面調(diào)用了非NSString的方法,會產(chǎn)生警告。
    接著,你創(chuàng)建了一個NSData對象,然后把這個對象所在的內(nèi)存地址保存在str里。那么運行時,str指向的內(nèi)存空間就是一個NSData對象。你可以把str當做一個NSData對象來用。
    28.socket通信的幾個關(guān)鍵步驟
    面向連接的socket通信就像與對方打電話,首先需要通過電話建立一個連接,連接建立好之后,彼此才能雙向通信。它有幾個關(guān)鍵步驟
    服務(wù)器端通常以守護進程的方式實現(xiàn):
    1:創(chuàng)建守護進程
    2:獲取或注冊服務(wù)
    3:創(chuàng)建socket并綁定地址
    4:開始監(jiān)聽
    5:接收客戶端連接請求
    6:進行數(shù)據(jù)傳輸
    客戶端
    1:獲取或注冊服務(wù)
    2:創(chuàng)建socket
    3:發(fā)送連接請求
    29.類別意義?與繼承的區(qū)別
    當我們添加頭文件以后,對已知的類,會自動提示你對這個類添加的方法
    主要用途,對于原生不會造成破壞,使用原生就可以提示出你的方法
    30.Core Foundation中提供了哪幾種操作Socket的方法?
    CFNetwork、CFSocket和BSDSocket
    31.用id聲明的對象有什么特性?
    ?沒有

    ?動態(tài)數(shù)據(jù)類型
    ?可以指向任何類的對象(設(shè)置是nil),而不關(guān)心其具體類型
    ?在運行時檢查其具體類型
    ?可以對其發(fā)送任何(存在的)消息
    32,self.name=“object”name=“object”有什么區(qū)別?
    前者實際上是調(diào)用了set方法給變量賦值而后者是直接給變量賦值
    33.shell中,將command1的輸出作為command2的輸出應(yīng)該使用的命令是?
    重定向命令>
    command1>command2
    34.下面的數(shù)據(jù)結(jié)構(gòu)中不屬于線性結(jié)構(gòu)的是:棧,鏈表,二叉樹,線性表
    線性結(jié)構(gòu):棧,鏈表,線性表
    非線性結(jié)構(gòu):二叉樹
    35,oc中有沒有多繼承,如果沒有用什么方法替代?
    沒有用協(xié)議代替多繼承
    36.常見的Objective-C的數(shù)據(jù)類型有哪些,和C的基本數(shù)據(jù)類型有什么區(qū)別
    OC中常用數(shù)據(jù)類型有NSArray,NSDictionary,NSData,NSString,NSMutbleString等等,和C的最大區(qū)別為OC中的類型是類類型,需要實例化對象才能用。C中是一般數(shù)據(jù)類型直接操作內(nèi)存空間
    37.self.name=@“aa”和_name=@“aa”的區(qū)別
    答:self.name=@“aa”是通過set方法進行賦值,_name=@“aa”是直接復(fù)制給成員變量
    38.C語言中指針與數(shù)組的區(qū)別
    答:指針是變量可以修改指向的方向,數(shù)組名是地址常量,不能被修改
    39.new delete malloc free的含義
    c++:new申請內(nèi)存,delete釋放掉指針指向的內(nèi)存
    c:malloc動態(tài)申請內(nèi)存,free釋放指針指向的內(nèi)存
    40.常引用什么時候使用
    如果既要利用引用提高程序的效率,又要保護傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被改變,就要使用常引用
    41.c/oc/c++有什么區(qū)別和聯(lián)系
    C相對于C++和OC而言更偏重于邏輯算法,這是因為C是面向過程,C++和OC都是面向?qū)ο蟆和C++的聯(lián)系:C是C++的一個自洽子集,C++是C的超集,OC是C的擴展,C++和OC基本兼容C的語法。
    42.const的用法
    const修飾變量表示該變量是只讀變量(有些人管它叫常量),即只能引用而不能修改
    constint p;表示指針變量P指向的數(shù)據(jù)不能改
    int
    const p;表示指針變量P的值不能該,或者說是指針P的指向不能改
    43.[pool release]和[pool drain]有什么區(qū)別
    drain和release都會促使自動釋放池對象向池內(nèi)的每一個對象發(fā)送release消息來釋放池內(nèi)對象的引用計數(shù),但是release觸發(fā)的這個操作,不會考慮對象是否需要release,而drain會在自動釋放池向池內(nèi)對象發(fā)送release消息的時候,考慮對象是否需要release
    44.自動釋放池和GC一樣嗎,iphone有沒有GC
    在引用計數(shù)環(huán)境下,
    ios是沒有垃圾回收的,自動釋放池是oc中管理內(nèi)存的一種方式,它和gc是本質(zhì)區(qū)別的,自動釋放池管理內(nèi)存的前提是,必須把要管理內(nèi)存的對象加入池內(nèi),才會生效。而gc是不斷檢測當前程序中是否有不再使用的內(nèi)存進而釋放。
    45.當A類 中的某個方法執(zhí)行到某處時,這時想在B類中執(zhí)行某個方法,如何做?并做簡單說明
    用代理執(zhí)行代理方法
    說明:在b類中實現(xiàn)協(xié)議方法,設(shè)置a的代理為b,在指定方法內(nèi)調(diào)用代理的協(xié)議方法
    46.類別的作用?
    答案:category可以在不獲悉,不改變原來代碼的情況下往里面添加新的方法,只能添加,不能刪除修改。
    并且如果類別和原來類中的方法產(chǎn)生名稱沖突,則類別將覆蓋原來的方法,因為類別具有更高的優(yōu)先級。
    類別主要有3個作用:
    (1)將類的實現(xiàn)分散到多個不同文件或多個不同框架中。
    (2)創(chuàng)建對私有方法的前向引用。
    (3)向?qū)ο筇砑臃钦絽f(xié)議。
    47.簡述extern
    C的作用
    可以在C++中使用C的已編譯好的函數(shù)模塊,在c++中么用到c語言寫的函數(shù),聲明一下,在DLL中經(jīng)常看到,避免C++
    name mangling,主要用于動態(tài)鏈接庫,使得導(dǎo)出函數(shù)名稱與C語言規(guī)則一致(不改變),方便不同的編譯器甚至是不同的開發(fā)語言調(diào)用。
    extern
    "C"是告訴C++編譯器以C Linkage方式編譯,也就是抑制C++的name
    mangling機制。
    編程:
1.寫出@proerty(nonatomic,retain)Person
*person;@synthesize person具體實現(xiàn)。
- (void)setPerson:(Person *)person
{
if(_person !=person){
[_personrelease];
[_person =person retain];
}

}
- (Person *)person {
return _person;
}

2.從普通id類型對象轉(zhuǎn)換成數(shù)字對象,因為配置了限定詞.1f,所以結(jié)果四舍五入,并保留一位小數(shù)

NSDictionary* rowData =[NSDictionarydictionaryWithObjectsAndKeys:@"46.95",@"price",nil];
NSLog(@"a double value:%.1f",[(NSNumber*)[rowDataobjectForKey:@"price"] doubleValue]);
輸出:
a double value:47.0

3,寫一個委托的interface

#import
@protocolMyDelegate;//聲明
@interfaceMyClass:NSobject
{
iddelegate;
}
@end
@protocolMyDelegate//委托方法
-(void)selector:(NSString *)args;
@end

4:請看下面一段代碼

staticint a=1;
intmain(){
intb=2;
char*c=NUll;
c=(char*)malloc(100*sizeof(char));
return0;
}

問:1,訪問abc三者的效率從高到低依次是:
bca
2,在最壞情況下排序速度最快的是:歸并排序
復(fù)雜度最高的是:快排
a,快排,冒泡,堆,歸并
5.看下面的程序

=========================================
NSMutableArray *arr = [[NSMutableArrayarray] retain];
NSString *str = [NSStringstringWithFormat:@"test"];
[str retain];
[arr addObject:str];
NSLog(@"%@%lu",str,[strretainCount]);
[str retain];
[str release];
[str release];
NSLog(@"%@%lu",str,[strretainCount]);
[arr removeObject:str];
NSLog(@"%@%lu",str,[strretainCount]);
==================================================
三次打印的retainCount分別是什么,為什么?
答:
分別是3,2,1,
初始化的時候的為1,retain的時候+1,往數(shù)組里add的時候+1,release的時候-1,從數(shù)組里移除的時候-1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內(nèi)容

  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,195評論 30 471
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,721評論 18 399
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,324評論 11 349
  • 37.cocoa內(nèi)存管理規(guī)則 1)當你使用new,alloc或copy方法創(chuàng)建一個對象時,該對象的保留計數(shù)器值為1...
    如風家的秘密閱讀 878評論 0 4
  • 29.理解引用計數(shù) Objective-C語言使用引用計數(shù)來管理內(nèi)存,也就是說,每個對象都有個可以遞增或遞減的計數(shù)...
    Code_Ninja閱讀 1,517評論 1 3