說(shuō)說(shuō)你對(duì) OC 中 load 方法和 initialize 方法的異同肩袍〗垢ǎ——主要說(shuō)一下執(zhí)行時(shí)間博杖,各自用途,沒(méi)實(shí)現(xiàn)子類的方法會(huì)不會(huì)調(diào)用父類的筷登?
說(shuō)說(shuō)你對(duì) block 的理解剃根。—— 三種 block前方,棧上的自動(dòng)復(fù)制到堆上狈醉,block 的屬性修飾符是 copy,循環(huán)引用的原理和解決方案惠险。
說(shuō)說(shuō)你對(duì) runtime 的理解苗傅。——主要是方法調(diào)用時(shí)如何查找緩存班巩,如何找到方法金吗,找不到方法時(shí)怎么轉(zhuǎn)發(fā),對(duì)象的內(nèi)存布局趣竣。
提高方法查找機(jī)制效率-Class Cache
通過(guò)上文我們知道摇庙,在OC中,方法是通過(guò)isa指針遥缕,查找Class中的Method list來(lái)查詢的卫袒。而一個(gè)類往往會(huì)實(shí)現(xiàn)很多方法,每次調(diào)用都查詢一次Method list的分發(fā)表(dispatch table)的代價(jià)是很高的(因?yàn)榈ハ唬@種查詢可能每個(gè)RunLoop就執(zhí)行上億次)夕凝。這也就引入了Class Cache.
Class Cache認(rèn)為,當(dāng)一個(gè)方法被調(diào)用户秤,那么它之后被調(diào)用的可能性比較大码秉。
舉個(gè)例子,我們常見(jiàn)的alloc,init鸡号,調(diào)用順序如下
CustomObject * obj = [[CustomObject alloc] init];
alloc是類方法转砖,沿著isa找到CustomObject類元對(duì)象,發(fā)現(xiàn)沒(méi)有實(shí)現(xiàn)alloc
沿著super,找到NSObject類元方法府蔗,執(zhí)行alloc方法晋控,并把a(bǔ)lloc加入到NSObject類元對(duì)象的Class Cache中
init是實(shí)例方法,沿著isa找到CustomObject的類對(duì)象姓赤,發(fā)現(xiàn)沒(méi)有實(shí)現(xiàn)init
沿著super赡译,找到NSObject類對(duì)象,執(zhí)行init不铆,并把init加入到NSObject的類對(duì)象Class Cache中
這里蝌焚,再提一下alloc,init兩個(gè)方法
alloc方法的文檔
初始化isa誓斥,其他所有屬性被設(shè)為0
init
NSObject的init返回self只洒,其余的子類要調(diào)用[super init]進(jìn)行必要的初始化工作。
為什么要放在一起寫(xiě)岖食?
因?yàn)閍lloc和init有可能返回不同的對(duì)象
id a = [NSMutableArray alloc];
id b = [a init];
NSLog(@"%p",a);
NSLog(@"%p",b);
輸出
0x7fc550400fb0
0x7fc5505523a0
- 方法的selector
這兩個(gè)參數(shù)為方法的實(shí)現(xiàn)提供了調(diào)用者的信息红碑。之所以說(shuō)是隱藏的,是因?yàn)樗鼈冊(cè)诙x方法的源代碼中沒(méi)有聲明泡垃。它們是在編譯期被插入實(shí)現(xiàn)代碼的析珊。
雖然這些參數(shù)沒(méi)有顯示聲明,但在代碼中仍然可以引用它們蔑穴。我們可以使用self來(lái)引用接收者對(duì)象忠寻,使用_cmd來(lái)引用選擇器。如下代碼所示:
- strange
{
id target = getTheReceiver();
SEL method = getTheMethod();
if ( target == self || method == _cmd )
return nil;
return [target performSelector:method];
}
當(dāng)然存和,這兩個(gè)參數(shù)我們用得比較多的是self奕剃,_cmd在實(shí)際中用得比較少。
獲取方法地址
Runtime中方法的動(dòng)態(tài)綁定讓我們寫(xiě)代碼時(shí)更具靈活性捐腿,如我們可以把消息轉(zhuǎn)發(fā)給我們想要的對(duì)象纵朋,或者隨意交換一個(gè)方法的實(shí)現(xiàn)等。不過(guò)靈活性的提 升也帶來(lái)了性能上的一些損耗茄袖。畢竟我們需要去查找方法的實(shí)現(xiàn)操软,而不像函數(shù)調(diào)用來(lái)得那么直接。當(dāng)然宪祥,方法的緩存一定程度上解決了這一問(wèn)題聂薪。
我們上面提到過(guò),如果想要避開(kāi)這種動(dòng)態(tài)綁定方式蝗羊,我們可以獲取方法實(shí)現(xiàn)的地址藏澳,然后像調(diào)用函數(shù)一樣來(lái)直接調(diào)用它。特別是當(dāng)我們需要在一個(gè)循環(huán)內(nèi)頻繁地調(diào)用一個(gè)特定的方法時(shí)耀找,通過(guò)這種方式可以提高程序的性能翔悠。
NSObject類提供了methodForSelector:方法,讓我們可以獲取到方法的指針,然后通過(guò)這個(gè)指針來(lái)調(diào)用實(shí)現(xiàn)代碼凉驻。我們需要將methodForSelector:返回的指針轉(zhuǎn)換為合適的函數(shù)類型腻要,函數(shù)參數(shù)和返回值都需要匹配上复罐。
我們通過(guò)以下代碼來(lái)看看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ù)指針的前兩個(gè)參數(shù)必須是id和SEL涝登。
當(dāng)然這種方式只適合于在類似于for循環(huán)這種情況下頻繁調(diào)用同一方法,以提高性能的情況效诅。另外胀滚,methodForSelector:是由Cocoa運(yùn)行時(shí)提供的;它不是Objective-C語(yǔ)言的特性乱投。
消息轉(zhuǎn)發(fā)
當(dāng)一個(gè)對(duì)象能接收一個(gè)消息時(shí)咽笼,就會(huì)走正常的方法調(diào)用流程。但如果一個(gè)對(duì)象無(wú)法接收指定消息時(shí)戚炫,又會(huì)發(fā)生什么事呢剑刑?默認(rèn)情況下,如果是以 [object message]的方式調(diào)用方法双肤,如果object無(wú)法響應(yīng)message消息時(shí)施掏,編譯器會(huì)報(bào)錯(cuò)。但如果是以perform…的形式來(lái)調(diào)用茅糜,則需要等到運(yùn) 行時(shí)才能確定object是否能接收message消息七芭。如果不能,則程序崩潰蔑赘。
通常狸驳,當(dāng)我們不能確定一個(gè)對(duì)象是否能接收某個(gè)消息時(shí),會(huì)先調(diào)用respondsToSelector:來(lái)判斷一下缩赛。如下代碼所示:
if ([self respondsToSelector:@selector(method)]) {
[self performSelector:@selector(method)];
}
不過(guò)耙箍,我們這邊想討論下不使用respondsToSelector:判斷的情況。這才是我們這一節(jié)的重點(diǎn)酥馍。
當(dāng)一個(gè)對(duì)象無(wú)法接收某一消息時(shí)辩昆,就會(huì)啟動(dòng)所謂”消息轉(zhuǎn)發(fā)(message forwarding)“機(jī)制,通過(guò)這一機(jī)制物喷,我們可以告訴對(duì)象如何處理未知的消息卤材。默認(rèn)情況下,對(duì)象接收到未知的消息峦失,會(huì)導(dǎo)致程序崩潰扇丛,通過(guò)控制臺(tái),我們可以看到以下異常信息:
-[SUTRuntimeMethod method]: unrecognized selector sent to instance 0x100111940
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SUTRuntimeMethod method]: unrecognized selector sent to instance 0x100111940'
這段異常信息實(shí)際上是由NSObject的”doesNotRecognizeSelector”方法拋出的尉辑。不過(guò)帆精,我們可以采取一些措施,讓我們的程序執(zhí)行特定的邏輯,而避免程序的崩潰卓练。
消息轉(zhuǎn)發(fā)機(jī)制基本上分為三個(gè)步驟:
- 動(dòng)態(tài)方法解析
- 備用接收者
- 完整轉(zhuǎn)發(fā)
下面我們?cè)敿?xì)討論一下這三個(gè)步驟隘蝎。
動(dòng)態(tài)方法解析
對(duì)象在接收到未知的消息時(shí),首先會(huì)調(diào)用所屬類的類方法+resolveInstanceMethod:(實(shí)例方法)或 者+resolveClassMethod:(類方法)襟企。在這個(gè)方法中嘱么,我們有機(jī)會(huì)為該未知消息新增一個(gè)”處理方法”“。不過(guò)使用該方法的前提是我們已經(jīng) 實(shí)現(xiàn)了該”處理方法”顽悼,只需要在運(yùn)行時(shí)通過(guò)class_addMethod函數(shù)動(dòng)態(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];
}
不過(guò)這種方案更多的是為了實(shí)現(xiàn)@dynamic屬性。
備用接收者
如果在上一步無(wú)法處理消息蔚龙,則Runtime會(huì)繼續(xù)調(diào)以下方法:
- (id)forwardingTargetForSelector:(SEL)aSelector
如果一個(gè)對(duì)象實(shí)現(xiàn)了這個(gè)方法冰评,并返回一個(gè)非nil的結(jié)果,則這個(gè)對(duì)象會(huì)作為消息的新接收者木羹,且消息會(huì)被分發(fā)到這個(gè)對(duì)象甲雅。當(dāng)然這個(gè)對(duì)象不能是self自身,否則就是出現(xiàn)無(wú)限循環(huán)坑填。當(dāng)然抛人,如果我們沒(méi)有指定相應(yīng)的對(duì)象來(lái)處理aSelector,則應(yīng)該調(diào)用父類的實(shí)現(xiàn)來(lái)返回結(jié)果穷遂。
使用這個(gè)方法通常是在對(duì)象內(nèi)部函匕,可能還有一系列其它對(duì)象能處理該消息,我們便可借這些對(duì)象來(lái)處理消息并返回蚪黑,這樣在對(duì)象外部看來(lái)盅惜,還是由該對(duì)象親自處理了這一消息。如下代碼所示:
@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來(lái)處理
if ([selectorString isEqualToString:@"method2"]) {
return _helper;
}
return [super forwardingTargetForSelector:aSelector];
}
@end
這一步合適于我們只想將消息轉(zhuǎn)發(fā)到另一個(gè)能處理該消息的對(duì)象上忌穿。但這一步無(wú)法對(duì)消息進(jìn)行處理抒寂,如操作消息的參數(shù)和返回值。
完整消息轉(zhuǎn)發(fā)
如果在上一步還不能處理未知消息掠剑,則唯一能做的就是啟用完整的消息轉(zhuǎn)發(fā)機(jī)制了屈芜。此時(shí)會(huì)調(diào)用以下方法:
- (void)forwardInvocation:(NSInvocation *)anInvocation
運(yùn)行時(shí)系統(tǒng)會(huì)在這一步給消息接收者最后一次機(jī)會(huì)將消息轉(zhuǎn)發(fā)給其它對(duì)象。對(duì)象會(huì)創(chuàng)建一個(gè)表示消息的NSInvocation對(duì)象朴译,把與尚未處理的消息 有關(guān)的全部細(xì)節(jié)都封裝在anInvocation中井佑,包括selector,目標(biāo)(target)和參數(shù)眠寿。我們可以在forwardInvocation 方法中選擇將消息轉(zhuǎn)發(fā)給其它對(duì)象躬翁。
//內(nèi)存布局
http://blog.csdn.net/cx_wzp/article/details/50905708
說(shuō)說(shuō)你對(duì) MVC 和 MVVM 的理解《⒐埃—— MVC 的 C 太臃腫盒发,可以和 V 合并例嘱,變成 MVVM 中的 V,而 VM 用來(lái)將 M 轉(zhuǎn)化成 V 能用的數(shù)據(jù)宁舰。
說(shuō)說(shuō) UITableView 的調(diào)優(yōu)拼卵。——一方面是通過(guò) instruments 檢查影響性能的地方蛮艰,另一方面是估算高度并在 runloop 空閑時(shí)緩存腋腮。
談?wù)勀銓?duì) ARC 的理解。ARC 是編譯器完成的印荔,依靠引用計(jì)數(shù)低葫,談?wù)剮讉€(gè)屬性修飾符的內(nèi)存管理策略详羡,什么情況下會(huì)內(nèi)存泄露
7仍律、層和UIView的區(qū)別是什么?
答:兩者最大的區(qū)別是,圖層不會(huì)直接渲染到屏幕上实柠,UIView是iOS系統(tǒng)中界面元素的基礎(chǔ)水泉,所有的界面元素都是繼承自它。它本身完全是由CoreAnimation來(lái)實(shí)現(xiàn)的窒盐。它真正的繪圖部分草则,是由一個(gè)CALayer類來(lái)管理。UIView本身更像是一個(gè)CALayer的管理器蟹漓。一個(gè)UIView上可以有n個(gè)CALayer炕横,每個(gè)layer顯示一種東西,增強(qiáng)UIView的展現(xiàn)能力葡粒。
3份殿、垃圾回收和引用計(jì)數(shù)的區(qū)別?引用計(jì)數(shù)為0了才釋放
2嗽交、自動(dòng)釋放池的作用卿嘲?
autorelease的使用
自動(dòng)釋放池:是用來(lái)自動(dòng)釋放對(duì)象的,不需要關(guān)心對(duì)象釋放的時(shí)間,不需要關(guān)心對(duì)象什么時(shí)候調(diào)用release
自動(dòng)釋放池釋放的時(shí)間:自動(dòng)釋放池結(jié)束
自動(dòng)釋放池原理:當(dāng)池子結(jié)束,會(huì)想池子里面的對(duì)象發(fā)送一條release消息
自動(dòng)釋放池使用:1.創(chuàng)建對(duì)象 2.加入自動(dòng)釋放池
兩種使用方式:
①Person *p = [Person new];
[p autorelease];
②Person *p1 = [[Person new]autorelease];
注意事項(xiàng):
1.并不是放到自動(dòng)釋放池中的代碼中夫壁,就會(huì)自動(dòng)加入到自動(dòng)釋放池的
需要我們調(diào)用autorelease方法的
在自動(dòng)釋放池的外部調(diào)用autorelease方法拾枣,是不會(huì)被加入到自動(dòng)釋放池中的
不管這個(gè)對(duì)象是在自動(dòng)釋放池內(nèi)部還是外部創(chuàng)建的,只要在這個(gè)對(duì)象在自動(dòng)釋放池中調(diào)用autorelease方法盒让,那么就會(huì)被放到自動(dòng)釋放池中
總結(jié):不管是在什么地方創(chuàng)建的對(duì)象梅肤,都必須在自動(dòng)釋放池中,調(diào)用autorelease方法邑茄,才會(huì)被加入自動(dòng)釋放池中
2.自動(dòng)釋放池的嵌套使用:自動(dòng)釋放池是個(gè)棧結(jié)構(gòu)姨蝴,先進(jìn)后出(每個(gè)自動(dòng)釋放池就當(dāng)成一個(gè)桶,先放到下面的撩扒,最后拿出來(lái)似扔,有利于理解)
延遲調(diào)用release吨些,在自動(dòng)釋放池結(jié)束時(shí),讓對(duì)象調(diào)用release
注意:自動(dòng)釋放池可不是直接釋放對(duì)象炒辉,而只是讓對(duì)象release一次豪墅,如果對(duì)象的retainCount為2,那么自動(dòng)釋放池只能讓retainCount變?yōu)?黔寇,對(duì)象就銷毀不了
3.自動(dòng)釋放池中不適合放占用內(nèi)存比較大的對(duì)象
1)這是種延遲釋放機(jī)制偶器,是直到自動(dòng)釋放池結(jié)束才釋放的,中間大內(nèi)存文件一直在占用內(nèi)存
2)不要把大量循環(huán)操作放到同一個(gè)@autoreleasepool(自動(dòng)釋放池)之間缝裤,這樣會(huì)造成內(nèi)存峰值的
4.錯(cuò)誤用法:
1)連續(xù)調(diào)用多次autorelease屏轰,釋放池結(jié)束時(shí)會(huì)執(zhí)行兩次release
? 注意:一個(gè)retainCount為1的對(duì)象,如果release兩次憋飞,程序是會(huì)崩潰的
· 2)alloc之后調(diào)用了autorelease霎苗,之后又調(diào)用了release(還是release兩次)
5.autorelease的應(yīng)用場(chǎng)景:
經(jīng)常用來(lái)在類方法中,快速創(chuàng)建一個(gè)對(duì)象
我們平常定義一個(gè)指針榛做,先alloc,再init唁盏,最后還要手動(dòng)釋放,太麻煩检眯,索性直接當(dāng)定義出來(lái)的同時(shí)厘擂,調(diào)用一下autorelease方法,當(dāng)自動(dòng)釋放池結(jié)束的時(shí)候锰瘸,自動(dòng)就release刽严,通常可以用于重寫(xiě)init的時(shí)候避凝,直接放在init里
【小結(jié)】:
1:自動(dòng)釋放池的數(shù)據(jù)結(jié)構(gòu)
自動(dòng)釋放池是以棧的形式實(shí)現(xiàn)舞萄,當(dāng)你創(chuàng)建一個(gè)新的自動(dòng)釋放池,它將會(huì)被添加到棧頂恕曲。接受autorelease
消息的對(duì)象將會(huì)唄放入棧頂
2:如何持有對(duì)象
當(dāng)我們使用alloc鹏氧,copy,retain對(duì)象獲取一個(gè)對(duì)象時(shí),我們需要負(fù)責(zé)顯示的安排對(duì)象的銷毀佩谣,其他方法獲取的
的對(duì)象將交給自動(dòng)釋放池進(jìn)行釋放(單例模式除外)
3:release和drain的區(qū)別
當(dāng)我們向自動(dòng)釋放池pool發(fā)送release消息把还,將會(huì)向池中臨時(shí)對(duì)象發(fā)送一條release消息,并且自身也會(huì)唄銷毀茸俭。
向它發(fā)送drain消息時(shí)吊履,只會(huì)指定前者。
1.Objective-C可以實(shí)現(xiàn)多繼承嗎调鬓?可以實(shí)現(xiàn)多個(gè)接口嗎艇炎?Category是什么?重寫(xiě)一個(gè)類的方式是用繼承好還是用分類好腾窝?為什么缀踪?
2.OC使用協(xié)議實(shí)現(xiàn)多繼承居砖,可以遵守多個(gè)協(xié)議實(shí)現(xiàn)多接口。category是OC中的類別驴娃,類別是用于給一個(gè)現(xiàn)有類添加新方法奏候。重寫(xiě)類一般采用繼承的方式,分類(類別)在給以個(gè)類添加同名方法后唇敞,會(huì)造成原有類中方法的實(shí)效蔗草,而繼承重寫(xiě)的方法,依然可以在使用父類對(duì)象調(diào)用該方法疆柔。
3.定義屬性的時(shí)候咒精,什么時(shí)候使用retain/copy/assign?寫(xiě)一個(gè)setter方法旷档,用于完成@property(nonatomic,retain) NSString* name;寫(xiě)一個(gè)setter方法模叙,用于完成@property(nonatomic,copy)NSString* name;
retain用于保留對(duì)象的引用計(jì)數(shù),在使用retain聲明的屬性做賦值的時(shí)候彬犯,成員變量指針會(huì)保留被賦值對(duì)象的引用計(jì)數(shù)向楼。
copy聲明的屬性,在使用屬性賦值的時(shí)候會(huì)谐区,成員指針會(huì)指向新副本,這個(gè)副本是一個(gè)不可變副本逻卖,不論賦值對(duì)象是不是可變的宋列。
assign用于基本數(shù)據(jù)類型的屬性聲明,不涉及到內(nèi)存管理的問(wèn)題评也,也是缺省參數(shù)
retain聲明的屬性的setter方法展開(kāi)
- (void)setName:(NSString*)name
{
if(_name != name)
{
[_namerelease];
_name= [name retain];
}
}
copy聲明的屬性的setter方法展開(kāi)
- (void)setName:(NSString*)name
{
if(_name != name)
{
[_namerelease];
_name= [name copy];
}
}
4.什么時(shí)候使用NSMutableArray/什么時(shí)候使用NSArray
NSMutableArray一般在需要隨時(shí)更改數(shù)組結(jié)構(gòu)的時(shí)候使用
NSArray一般用于保存一些不需要修改邏輯的數(shù)據(jù)
5.實(shí)現(xiàn)字符串“I LOVE CHINA”反串成“CHINA LOVE I”
- pch文件的作用
.pch表示"precompiled header",這是一個(gè)你工程要用到的來(lái)自于外部框架的頭文件列表炼杖。xcode將編譯這些頭到文件,這將減少你在選擇Build或Build and Go時(shí)編譯項(xiàng)目的時(shí)間盗迟。通常用到的頭文件已經(jīng)自動(dòng)包含了pch坤邪,系統(tǒng)編譯每個(gè)cpp文件前,都會(huì)先include這個(gè)文件罚缕。這樣就節(jié)省了添加include的時(shí)間艇纺,相當(dāng)于加速編譯
還有就是可以再這里面放入宏,在整個(gè)工程中都可以用
7.怎樣解決重復(fù)編譯
ifndef _DEBUG
ifdef USE_MYLIB
................
endif
- awakeFromNib與viewDidLoad區(qū)別
awakeFromNib
當(dāng).nib文件被加載的時(shí)候邮弹,會(huì)發(fā)送一個(gè)awakeFromNib的消息到.nib文件中的每個(gè)對(duì)象黔衡,每個(gè)對(duì)象都可以定義自己的awakeFromNib函數(shù)來(lái)響應(yīng)這個(gè)消息,執(zhí)行一些必要的操作腌乡。也就是說(shuō)通過(guò)nib文件創(chuàng)建view對(duì)象是執(zhí)行awakeFromNib盟劫。
viewDidLoad
當(dāng)view對(duì)象被加載到內(nèi)存是就會(huì)執(zhí)行viewDidLoad,所以不管通過(guò)nib文件還是代碼的方式創(chuàng)建對(duì)象都會(huì)執(zhí)行viewDidLoad与纽。 - LayoutSubviews何時(shí)會(huì)被調(diào)用
當(dāng)要調(diào)整subViews時(shí)候侣签,需要重寫(xiě)layoutSubviews方法塘装。
1:初始化init方法時(shí)候不會(huì)觸發(fā)。
2:滾動(dòng)UIScrollView時(shí)會(huì)觸發(fā)
3:旋轉(zhuǎn)UIScreen時(shí)會(huì)觸發(fā)
4:當(dāng)改變view的值時(shí)候會(huì)觸發(fā)影所,前提是frame前后值發(fā)生了變化
5:當(dāng)改變UIview的大小時(shí)候會(huì)觸發(fā) - public/private/protected的具體區(qū)別
public公共氢哮,加上這個(gè)修飾的類或?qū)傩裕梢栽谕粋€(gè)包或者別的包里面訪問(wèn)
private私有的型檀,加上這個(gè)修飾的類或?qū)傩匀哂龋荒茉谕惱镌L問(wèn),同包和別的包不能訪問(wèn)
protected保護(hù)胀溺,加上這個(gè)修飾的類或?qū)傩粤哑撸荒茉陬惡屯L問(wèn),別的包不能訪問(wèn) - ARC是什么
ARC是iOS 5推出的新功能仓坞,全稱叫ARC(Automatic Reference Counting)背零。簡(jiǎn)單地說(shuō),就是代碼中自動(dòng)加入了retain/release无埃,原先需要手動(dòng)添加的用來(lái)處理內(nèi)存管理的引用計(jì)數(shù)的代碼可以自動(dòng)地由編譯器完成了徙瓶。
該機(jī)能在iOS 5/ Mac OS X 10.7開(kāi)始導(dǎo)入,利用Xcode4.2可以使用該機(jī)能嫉称。簡(jiǎn)單地理解ARC侦镇,就是通過(guò)指定的語(yǔ)法,讓編譯器(LLVM
3.0)在編譯代碼時(shí)织阅,自動(dòng)生成實(shí)例的引用計(jì)數(shù)管理部分代碼壳繁。有一點(diǎn),ARC并不是GC荔棉,它只是一種代碼靜態(tài)分析(Static
Analyzer)工具闹炉。
12.寫(xiě)一個(gè)“標(biāo)準(zhǔn)”宏,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的
define MIN(X,Y)((X)>(Y)?(Y):(X))
13.Objective-c中有多重繼承么润樱?不是的話有聲明替代方式?
沒(méi)有多繼承渣触,可以通過(guò)協(xié)議模擬多繼承
14.Objective-c中有私有方法嗎?私有變量呢壹若?
沒(méi)有私有方法嗅钻,但可以將方法直接實(shí)現(xiàn)在.m文件中不在.h文件中聲明時(shí),外部也不能訪問(wèn)舌稀。
有私有變量
15.iPhone OS中有沒(méi)有垃圾回收啊犬?
沒(méi)有
16.常見(jiàn)的object-c的數(shù)據(jù)類型有哪些,和c的基本類型有什么區(qū)別
答:常見(jiàn)的object-c的數(shù)據(jù)類型有NSInteger壁查、CGFloat觉至、NSString、NSNumber睡腿、NSArray语御、NSData峻贮,NSInteger會(huì)根據(jù)系統(tǒng)是32位還是64位來(lái)決定是本身是int還是Long,
CGFloat會(huì)根據(jù)系統(tǒng)是32位還是64位來(lái)決定是本身是float還是double,NSString、NSNumber应闯、NSArray纤控、NSData都是指針類型的對(duì)象,在堆中分配空間,而c語(yǔ)言中的char碉纺,[]等都是在棧中分配空間
17.id聲明的對(duì)象有什么特性船万?
id聲明的對(duì)象具有運(yùn)行時(shí)的特性,即可以指向任意類型的objcetive-c的對(duì)象骨田;
18.想nil對(duì)象發(fā)送消息會(huì)發(fā)生什么耿导?
答:在Objective-C中向nil發(fā)送消息是完全有效的,只是在運(yùn)行時(shí)不會(huì)有任何作用态贤。
19.什么是block舱呻?block實(shí)現(xiàn)原理?
答:block是一個(gè)特殊的OC對(duì)象,它建立在棧上,而不是堆上,這么做一個(gè)是為性能考慮,還有就是方便訪問(wèn)局部變量悠汽。默認(rèn)情況下block使用到的局部變量都會(huì)被復(fù)制,而不是保留箱吕。所以它無(wú)法改變局部變量的值。如果在變量面前加上__block,那么編譯器回去不會(huì)復(fù)制變量,而是去找變量的地址,通過(guò)地址來(lái)訪問(wèn)變量,實(shí)際上就是直接操作變量柿冲。另外block是在棧上分配的,所以一旦離開(kāi)作用域,就會(huì)釋放,因此如果你要把快用在別的地方,必須要復(fù)制一份茬高。block是不能保留的,
retain對(duì)塊沒(méi)有意義。
20.C++和OC姻采,JAVA和OC之間的區(qū)別雅采?
C++是功能強(qiáng)大,豐富的面向?qū)ο缶幊陶Z(yǔ)言慨亲,具有私有、公有宝鼓、保護(hù)權(quán)限的三種成員變量和成員方法刑棵,具有私有、公有愚铡、保護(hù)三種繼承方式蛉签,具有重寫(xiě),重載沥寥,虛函數(shù)碍舍,虛基類等多態(tài)方式,通過(guò)虛基類實(shí)現(xiàn)代理回調(diào)邑雅。自定義類可以沒(méi)有父類片橡。另外具備向量,模板淮野,友元捧书,重載運(yùn)算符等多種獨(dú)特語(yǔ)法
Obj-C是針對(duì)mac OS和iOS設(shè)備應(yīng)用程序開(kāi)發(fā)的專屬編程語(yǔ)言吹泡,采用動(dòng)態(tài)繼承,消息方法機(jī)制经瓷,沒(méi)有真正的重寫(xiě)機(jī)制爆哑,沒(méi)有私有方法,繼承方式為公有舆吮,具備協(xié)議揭朝,類別,Block等獨(dú)有的語(yǔ)法色冀,萬(wàn)用父類為NSObject
JAVA是老牌的面向?qū)ο笳Z(yǔ)言潭袱,編寫(xiě)的程序在JAVA虛擬機(jī)上運(yùn)行,真正實(shí)現(xiàn)了一次編譯到處運(yùn)行呐伞,具有復(fù)雜的內(nèi)存回收機(jī)制敌卓,單繼承模式,接口語(yǔ)法類似Obj-C的協(xié)議
21.抽象與接口的區(qū)別伶氢?
聲明方法的存在而不去實(shí)現(xiàn)它的類被叫做抽象類(abstract class)趟径,它用于要?jiǎng)?chuàng)建一個(gè)體現(xiàn)某些基本行為的類,并為該類聲明方法癣防,但不能在該類中實(shí)現(xiàn)該類的情況蜗巧。不能創(chuàng)建abstract類的實(shí)例。然而可以創(chuàng)建一個(gè)變量蕾盯,其類型是一個(gè)抽象類幕屹,并讓它指向具體子類的一個(gè)實(shí)例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法级遭。Abstract類的子類為它們父類中的所有抽象方法提供實(shí)現(xiàn)望拖,否則它們也是抽象類為。取而代之挫鸽,在子類中實(shí)現(xiàn)該方法说敏。知道其行為的其它類可以在類中實(shí)現(xiàn)這些方法。
接口(interface)是抽象類的變體丢郊。在接口中盔沫,所有方法都是抽象的。多繼承性可通過(guò)實(shí)現(xiàn)這樣的接口而獲得枫匾。接口中的所有方法都是抽象的架诞,沒(méi)有一個(gè)有程序體。接口只可以定義static
final成員變量干茉。接口的實(shí)現(xiàn)與子類相似谴忧,除了該實(shí)現(xiàn)類不能從接口定義中繼承行為。當(dāng)類實(shí)現(xiàn)特殊接口時(shí),它定義(即將程序體給予)所有這種接口的方法俏蛮。然后撑蚌,它可以在實(shí)現(xiàn)了該接口的類的任何對(duì)象上調(diào)用接口的方法。由于有抽象類搏屑,它允許使用接口名作為引用變量的類型争涌。通常的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到接口類型或從接口類型轉(zhuǎn)換辣恋,instanceof運(yùn)算符可以用來(lái)決定某對(duì)象的類是否實(shí)現(xiàn)了接口亮垫。
22.nil與NULL的區(qū)別?
從Objective-C語(yǔ)言的官方說(shuō)法上看伟骨,nil表示指向?qū)ο蟮闹羔樇此^對(duì)象的引用為空饮潦,NULL表示指向基礎(chǔ)類型變量即C語(yǔ)言變量的指針為空。如果在非ARC程序的編寫(xiě)過(guò)程中携狭,兩個(gè)空是可以互換的继蜡,但是在ARC環(huán)境下,普通指針和對(duì)象引用被嚴(yán)格限制逛腿,不能交換使用稀并,因此也應(yīng)盡量不互換使用nil與NULL
- BOOL與bool的區(qū)別?
bool是C語(yǔ)言C99標(biāo)準(zhǔn)中增添的變量類型单默,Object-C僅僅是從C語(yǔ)言繼承了這種類型碘举,該類型有true和false兩個(gè)值,表示真和假搁廓。BOOL是Obj-C獨(dú)有的布爾類型引颈,有YES和NO兩個(gè)值,分別是1和0的宏境蜕。Obj-C中同時(shí)認(rèn)為所有非0的值都是真值蝙场,0為假值
24.OC如何實(shí)現(xiàn)私有方法?
Obj-C語(yǔ)法中并沒(méi)有私有方法的概念,但是由于Obj-C是通過(guò)導(dǎo)入其他類的頭文件來(lái)獲取其他類所擁有的成員方法的聲明粱年,因此可以采用編寫(xiě)方法時(shí)李丰,不聲明,或僅在.m文件中的匿名類別中聲明的方式逼泣,使方法對(duì)外不可見(jiàn),即可達(dá)到方法私有化的目的舟舒。但是外部類仍然可以通過(guò)@selector來(lái)訪問(wèn)確實(shí)存在的私有方法拉庶,因此嚴(yán)格來(lái)講Obj-C確實(shí)不能真正實(shí)現(xiàn)方法私有化
25.#import和#include的區(qū)別@ class代表什么
預(yù)編譯指令
Objective-C:#import
C,C++:#include
import由gcc編譯器支持
在Objective-C中秃励,#import被當(dāng)成#include指令的改良版本來(lái)使用氏仗。除此之外,#import確定一個(gè)文件只能被導(dǎo)入一次,這使你在遞歸包含中不會(huì)出現(xiàn)問(wèn)題皆尔。
使用哪一個(gè)還是由你來(lái)決定呐舔。一般來(lái)說(shuō),在導(dǎo)入Objective-C頭文件的時(shí)候使用#import慷蠕,包含C頭文件時(shí)使用#include珊拼。比如:
import
include
include
import比起#include的好處就是不會(huì)引起交叉編譯
二、@class是用來(lái)做類引用的
@class就是告訴編譯器有這么一個(gè)類流炕,至于類的定義是啥不知道
@class一般用于頭文件中需要聲明該類的某個(gè)實(shí)例變量的時(shí)候用到澎现,在m文件中還是需要使用#import
- NSString和NSMutableString的區(qū)別
NSString是一個(gè)不可變的字符串對(duì)象。這不是表示這個(gè)對(duì)象聲明的變量的值不可變每辟,而是表示它初始化以后剑辫,你不能改變?cè)撟兞克峙涞膬?nèi)存中的值,但你可以重新分配該變量所處的內(nèi)存空間渠欺。而NSMutableString是可變的妹蔽,意味著你可以追加它的內(nèi)存空間,或者修改它所分配的內(nèi)存空間中的值挠将。
27..關(guān)于語(yǔ)句NSString * str= [NSData alloc]init,編譯和運(yùn)行分別str代表什么對(duì)象?
首先胳岂,聲明NSString str是告訴編譯器,str是一個(gè)指向某個(gè)Objective-C對(duì)象的指針捐名。因?yàn)椴还苤赶虻氖鞘裁搭愋偷膶?duì)象旦万,一個(gè)指針?biāo)嫉膬?nèi)存空間都是固定的,所以這里聲明成任何類型的對(duì)象镶蹋,最終生成的可執(zhí)行代碼都是沒(méi)有區(qū)別的成艘。這里限定了NSString只不過(guò)是告訴編譯器,請(qǐng)把str當(dāng)做一個(gè)NSString來(lái)檢查贺归,如果后面調(diào)用了非NSString的方法淆两,會(huì)產(chǎn)生警告。
接著拂酣,你創(chuàng)建了一個(gè)NSData對(duì)象秋冰,然后把這個(gè)對(duì)象所在的內(nèi)存地址保存在str里。那么運(yùn)行時(shí)婶熬,str指向的內(nèi)存空間就是一個(gè)NSData對(duì)象剑勾。你可以把str當(dāng)做一個(gè)NSData對(duì)象來(lái)用。
28.socket通信的幾個(gè)關(guān)鍵步驟
面向連接的socket通信就像與對(duì)方打電話赵颅,首先需要通過(guò)電話建立一個(gè)連接虽另,連接建立好之后,彼此才能雙向通信饺谬。它有幾個(gè)關(guān)鍵步驟
服務(wù)器端通常以守護(hù)進(jìn)程的方式實(shí)現(xiàn):
1:創(chuàng)建守護(hù)進(jìn)程
2:獲取或注冊(cè)服務(wù)
3:創(chuàng)建socket并綁定地址
4:開(kāi)始監(jiān)聽(tīng)
5:接收客戶端連接請(qǐng)求
6:進(jìn)行數(shù)據(jù)傳輸
客戶端
1:獲取或注冊(cè)服務(wù)
2:創(chuàng)建socket
3:發(fā)送連接請(qǐng)求
29.類別意義捂刺?與繼承的區(qū)別
當(dāng)我們添加頭文件以后,對(duì)已知的類,會(huì)自動(dòng)提示你對(duì)這個(gè)類添加的方法
主要用途族展,對(duì)于原生不會(huì)造成破壞森缠,使用原生就可以提示出你的方法
30.Core Foundation中提供了哪幾種操作Socket的方法?
CFNetwork仪缸、CFSocket和BSDSocket
31.用id聲明的對(duì)象有什么特性贵涵?
?沒(méi)有號(hào)
?動(dòng)態(tài)數(shù)據(jù)類型
?可以指向任何類的對(duì)象(設(shè)置是nil),而不關(guān)心其具體類型
?在運(yùn)行時(shí)檢查其具體類型
?可以對(duì)其發(fā)送任何(存在的)消息
32腹殿,self.name=“object”name=“object”有什么區(qū)別独悴?
前者實(shí)際上是調(diào)用了set方法給變量賦值而后者是直接給變量賦值
33.shell中,將command1的輸出作為command2的輸出應(yīng)該使用的命令是锣尉?
重定向命令>
command1>command2
34.下面的數(shù)據(jù)結(jié)構(gòu)中不屬于線性結(jié)構(gòu)的是:棧刻炒,鏈表,二叉樹(shù)自沧,線性表
線性結(jié)構(gòu):棧坟奥,鏈表,線性表
非線性結(jié)構(gòu):二叉樹(shù)
35拇厢,oc中有沒(méi)有多繼承爱谁,如果沒(méi)有用什么方法替代?
沒(méi)有用協(xié)議代替多繼承
36.常見(jiàn)的Objective-C的數(shù)據(jù)類型有哪些孝偎,和C的基本數(shù)據(jù)類型有什么區(qū)別
OC中常用數(shù)據(jù)類型有NSArray,NSDictionary,NSData,NSString,NSMutbleString等等访敌,和C的最大區(qū)別為OC中的類型是類類型,需要實(shí)例化對(duì)象才能用衣盾。C中是一般數(shù)據(jù)類型直接操作內(nèi)存空間
37.self.name=@“aa”和_name=@“aa”的區(qū)別
答:self.name=@“aa”是通過(guò)set方法進(jìn)行賦值寺旺,_name=@“aa”是直接復(fù)制給成員變量
38.C語(yǔ)言中指針與數(shù)組的區(qū)別
答:指針是變量可以修改指向的方向,數(shù)組名是地址常量势决,不能被修改
39.new delete malloc free的含義
c++:new申請(qǐng)內(nèi)存阻塑,delete釋放掉指針指向的內(nèi)存
c:malloc動(dòng)態(tài)申請(qǐng)內(nèi)存,free釋放指針指向的內(nèi)存
40.常引用什么時(shí)候使用
如果既要利用引用提高程序的效率果复,又要保護(hù)傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被改變陈莽,就要使用常引用
41.c/oc/c++有什么區(qū)別和聯(lián)系
C相對(duì)于C++和OC而言更偏重于邏輯算法,這是因?yàn)镃是面向過(guò)程虽抄,C++和OC都是面向?qū)ο笞吒椤和C++的聯(lián)系:C是C++的一個(gè)自洽子集,C++是C的超集迈窟,OC是C的擴(kuò)展朱盐,C++和OC基本兼容C的語(yǔ)法。
42.const的用法
const修飾變量表示該變量是只讀變量(有些人管它叫常量)菠隆,即只能引用而不能修改
constint p;表示指針變量P指向的數(shù)據(jù)不能改
intconst p;表示指針變量P的值不能該,或者說(shuō)是指針P的指向不能改
43.[pool release]和[pool drain]有什么區(qū)別
drain和release都會(huì)促使自動(dòng)釋放池對(duì)象向池內(nèi)的每一個(gè)對(duì)象發(fā)送release消息來(lái)釋放池內(nèi)對(duì)象的引用計(jì)數(shù),但是release觸發(fā)的這個(gè)操作骇径,不會(huì)考慮對(duì)象是否需要release躯肌,而drain會(huì)在自動(dòng)釋放池向池內(nèi)對(duì)象發(fā)送release消息的時(shí)候,考慮對(duì)象是否需要release
44.自動(dòng)釋放池和GC一樣嗎破衔,iphone有沒(méi)有GC
在引用計(jì)數(shù)環(huán)境下清女,
ios是沒(méi)有垃圾回收的,自動(dòng)釋放池是oc中管理內(nèi)存的一種方式晰筛,它和gc是本質(zhì)區(qū)別的嫡丙,自動(dòng)釋放池管理內(nèi)存的前提是,必須把要管理內(nèi)存的對(duì)象加入池內(nèi)读第,才會(huì)生效曙博。而gc是不斷檢測(cè)當(dāng)前程序中是否有不再使用的內(nèi)存進(jìn)而釋放。
45.當(dāng)A類 中的某個(gè)方法執(zhí)行到某處時(shí)怜瞒,這時(shí)想在B類中執(zhí)行某個(gè)方法父泳,如何做?并做簡(jiǎn)單說(shuō)明
用代理執(zhí)行代理方法
說(shuō)明:在b類中實(shí)現(xiàn)協(xié)議方法吴汪,設(shè)置a的代理為b惠窄,在指定方法內(nèi)調(diào)用代理的協(xié)議方法
46.類別的作用?
答案:category可以在不獲悉,不改變?cè)瓉?lái)代碼的情況下往里面添加新的方法漾橙,只能添加杆融,不能刪除修改怔软。
并且如果類別和原來(lái)類中的方法產(chǎn)生名稱沖突香到,則類別將覆蓋原來(lái)的方法,因?yàn)轭悇e具有更高的優(yōu)先級(jí)窗轩。
類別主要有3個(gè)作用:
(1)將類的實(shí)現(xiàn)分散到多個(gè)不同文件或多個(gè)不同框架中觉渴。
(2)創(chuàng)建對(duì)私有方法的前向引用介劫。
(3)向?qū)ο筇砑臃钦絽f(xié)議。
47.簡(jiǎn)述extern
C的作用
可以在C++中使用C的已編譯好的函數(shù)模塊,在c++中么用到c語(yǔ)言寫(xiě)的函數(shù)案淋,聲明一下,在DLL中經(jīng)匙希看到,避免C++
name mangling,主要用于動(dòng)態(tài)鏈接庫(kù)踢京,使得導(dǎo)出函數(shù)名稱與C語(yǔ)言規(guī)則一致(不改變)誉碴,方便不同的編譯器甚至是不同的開(kāi)發(fā)語(yǔ)言調(diào)用。
extern
"C"是告訴C++編譯器以C Linkage方式編譯瓣距,也就是抑制C++的name
mangling機(jī)制黔帕。
編程:
1.寫(xiě)出@proerty(nonatomic,retain)Person
*person;@synthesize person具體實(shí)現(xiàn)。
- (void)setPerson:(Person *)person
{
if(_person !=person){
[_personrelease];
[_person =person retain];
}
}
- (Person *)person {
return _person;
}
2.從普通id類型對(duì)象轉(zhuǎn)換成數(shù)字對(duì)象蹈丸,因?yàn)榕渲昧讼薅ㄔ~.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,寫(xiě)一個(gè)委托的interface
#import
@protocolMyDelegate;//聲明
@interfaceMyClass:NSobject
{
iddelegate;
}
@end
@protocolMyDelegate//委托方法
-(void)selector:(NSString *)args;
@end
4:請(qǐng)看下面一段代碼
staticint a=1;
intmain(){
intb=2;
char*c=NUll;
c=(char*)malloc(100*sizeof(char));
return0;
}
問(wèn):1奋岁,訪問(wèn)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畜份,
初始化的時(shí)候的為1诞帐,retain的時(shí)候+1,往數(shù)組里add的時(shí)候+1漂坏,release的時(shí)候-1景埃,從數(shù)組里移除的時(shí)候-1