知識(shí)點(diǎn)總結(jié)中,如有幸被您觀看,更有可能看到不足,期待指出交流
前言
這個(gè)是高手,這個(gè)是高手,這個(gè)是高手
方法和選擇器的不同
- selector 是一個(gè)方法的名字,method是一個(gè)組合體,包含了名字和實(shí)現(xiàn)
core foundation的內(nèi)存管理
- 凡是帶有create, copy, retain 等字眼的函數(shù),創(chuàng)建出來(lái)的對(duì)象, 都需要在最后做一次release
- 比如 CFRunLoopObserverCreate release函數(shù): CFRelease(對(duì)象)
malloc和new的區(qū)別
- new 是c++的操作符, malloc是c中的一個(gè)函數(shù)
- new 不止是是分配內(nèi)存,而且會(huì)調(diào)用類的構(gòu)造函數(shù),同理delete會(huì)調(diào)用類的析構(gòu)函數(shù),而malloc則只分配內(nèi)存,不會(huì)進(jìn)行初始化類成員的工作,同樣free也不會(huì)調(diào)用析構(gòu)函數(shù)
- new可以認(rèn)為是malloc加構(gòu)函數(shù)的執(zhí)行
- new 出來(lái)的指針是直接帶類型信息的
OC中的反射機(jī)制
- class反射
- 通過(guò)類名的字符串形式實(shí)例化對(duì)象
Class class NSClassFromString@(@"student");
student *stu = [[class alloc] init];
- 將類名變成字符串
Class class = [Student class];
NSString *className = NSStringFromClass(class);
- SEL的反射
- 通過(guò)方法的支付創(chuàng)新是實(shí)例化方法
SEL selector = NSSelectorFromClass(@"setName");
[stu performSelector:selector withObject:@"Mike"]; - 將方法變成字符串
NSStringFromSelector(@selector(*setName:))
SEL 理解和調(diào)用
理解:
- SEL 就是對(duì)方法的一種包裝.包裝的SEL類型數(shù)據(jù)它對(duì)應(yīng)相應(yīng)方法地址,找到方法地址就可以調(diào)用方法.在內(nèi)存中每個(gè)類的方法都儲(chǔ)存在類對(duì)象中,每個(gè)方法都有一個(gè)與之對(duì)應(yīng)的SEL類型數(shù)據(jù),根據(jù)一個(gè)SEL數(shù)據(jù)就可一個(gè)找到對(duì)應(yīng)的方法地址,進(jìn)而調(diào)用方法
- SEL s1 = @selector(tet1); // 將test1方法包裝成SEL對(duì)象
- SEL s2 = NSSelectorFromString(@"test1"); // 將一個(gè)字符串方法轉(zhuǎn)換成SEL對(duì)象
調(diào)用:
- 直接通過(guò)方法名來(lái)調(diào)用
- 間接的通過(guò)SEL數(shù)據(jù)來(lái)調(diào)用 SEL aaa = @selector(text);[person performSelector:aaa];
協(xié)議中<NSObject>是什么意思?子類繼承了父業(yè),那么子類會(huì)遵守父類中遵守的協(xié)議嗎?協(xié)議中能夠定義成員變量?如何約束一個(gè)對(duì)象類型的變量要存儲(chǔ)的地址是一個(gè)遵守一個(gè)協(xié)議對(duì)象?
- 遵守NSObject協(xié)議
- 會(huì)
- 能,但是只在頭文件中聲明,編譯器是不會(huì)自動(dòng)生成實(shí)例變量的.需要自己處理getter和setter方法
- id<XXX>
NS/CF/CG/CA/UI 這些前綴的含義
- 函數(shù)歸屬于 cocoa Fundation 框架
- 函數(shù)歸屬于 core Fundation 框架
- 函數(shù)歸屬于 coreGrahics.frameWorks 框架
- 函數(shù)歸屬于 UIKit 框架
面向?qū)ο蠖加心男┨卣饕约澳銓?duì)這些特征的理解
- 繼承:繼承是從已有類得到繼承信息創(chuàng)建新類的過(guò)程.提供繼承信息的類被成為父類(超類,基類);得到繼承信息的類被成為子類(派生類).繼承讓變化中的軟件系統(tǒng)有一定的延續(xù)性,同時(shí)繼承也是封裝程序中可變因素的重要手段
- 封裝:封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來(lái),對(duì)數(shù)據(jù)的訪問(wèn)只能通過(guò)已定義的接口.我們?cè)陬愔芯帉?xiě)的方法就是對(duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫(xiě)一個(gè)類就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝.可以說(shuō),封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程接口
- 多態(tài)性:多態(tài)性是指允許不同子類型的對(duì)象對(duì)統(tǒng)一消息做出不同的響應(yīng).簡(jiǎn)單的說(shuō)就是用同樣的對(duì)象調(diào)用同樣的方法但是做了不同的事情.多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性.方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也成為前綁定),而方法重寫(xiě)(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱后綁定).運(yùn)行時(shí)的多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)多態(tài)需要做兩件事:1.方法重寫(xiě)(子類繼承父類并重寫(xiě)父類中已有的或抽象的方法);2.對(duì)象造型(用父類型引用引用子類對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù)子類對(duì)象和不同而表現(xiàn)出不同的行為)
- 抽象:抽象是將一類對(duì)象的共同點(diǎn)特征總結(jié)出來(lái)構(gòu)造類的過(guò)程,包括數(shù)據(jù)抽象和行為抽象兩方面.抽象只關(guān)注對(duì)象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是什么.
Object-C,動(dòng)態(tài)運(yùn)行時(shí)語(yǔ)言
- 主要是將數(shù)據(jù)類型的確定由編譯時(shí),推遲到運(yùn)行時(shí).這個(gè)問(wèn)題其實(shí)淺涉及到兩個(gè)概念,運(yùn)行時(shí)和多態(tài)
- 簡(jiǎn)單的來(lái)說(shuō),運(yùn)行時(shí)機(jī)使我們直到運(yùn)行時(shí)才去確定一個(gè)對(duì)象的類別,以及調(diào)用該類別對(duì)象指定方法.
- 多態(tài):不同對(duì)象以自己的方式響應(yīng)相同的消息的能力叫多態(tài)
-意思就是建設(shè)生物類(list)都用用一個(gè)相同的方法-eat,人類屬于生物,豬也屬于生物,都繼承了list后,實(shí)現(xiàn)各自的-eat,但是調(diào)用使我們只需要調(diào)用各自的eat方法.也就是不同的對(duì)象都以自己的方式響應(yīng)了相同的消息(響應(yīng)了eat這個(gè)選擇器).因此也可以說(shuō),運(yùn)行時(shí)機(jī)制是多態(tài)的基礎(chǔ).
readwrite,readonly,assign,retain,copy,nonatomic屬性的作用?
- readwrite 是可讀可寫(xiě)特性,需要生成getter防范和setter方法
- readonly 是只讀特性 只會(huì)生成getter方法, 不會(huì)生成setter方法,不希望屬性在類外改變
- assign 是賦值特性, setter 方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí),assign用于簡(jiǎn)單數(shù)據(jù)類型,如NSInteger,double,bool;
- retain 表示持有特性,setter方法將傳入?yún)?shù)先保留,再賦值,傳入?yún)?shù)的引用計(jì)數(shù)retaincount會(huì)+1
- copy 便是賦值特性,setter方法會(huì)傳入對(duì)象復(fù)制一份;需要完全一份新的變量時(shí);
- nonatomic 非原子性操作,確定編譯器生成的seter getter 是否需要要原子操作;
- atomic 表示多線程安全, 一般使用 nonatiomic;
NotificationCenter,kvc,kvo,Delegate,區(qū)別
- KVO(Key-Value-Observing):一對(duì)多,觀察者模式,鍵值觀察機(jī)制,他提供了觀察某一屬性變化的方法,極大簡(jiǎn)化了代碼
- KVC(Key-Value-Coding):是鍵值編碼,一個(gè)對(duì)象在調(diào)用setValue
-- 檢查是否存在相應(yīng)key的set方法,車載就調(diào)用set方法
-- set方法不存在的,就查找_key的成員變量是否存在,存在就直接賦值
-- 如果_key沒(méi)有找到,就查找相同名稱的key,存在就賦值
-- 如果沒(méi)有就調(diào)用valueForUndefinedkey和setValue:forUndefinedKey. - Delegate:通常發(fā)送者和接受者的關(guān)系是直接的一對(duì)一關(guān)系
-- 代理的目的是改變或者傳遞控制鏈.允許一個(gè)類在某些特定時(shí)刻通知到其他類,而不需要要獲取到那些類的指針.
-- 可以減少框架復(fù)雜度.消息的發(fā)送者告知接收者某個(gè)事件將要發(fā)生,delegate同意然后發(fā)送響應(yīng)事件,delegate機(jī)制使得接受者可以改變發(fā)送者的行為 - Notification:觀察者模式,通常發(fā)送者和接受者的關(guān)系是間接的多對(duì)多關(guān)系.消息的發(fā)送者告知接受者事件已經(jīng)發(fā)生或者將要發(fā)送,僅此而已,接收者并不能反過(guò)來(lái)影響發(fā)送者的行為
- 區(qū)別
-- 效率肯定是delegate比NSNotification高.
-- delegate方法比notification更加直接,需要關(guān)注返回值,所以delegate方法往往包含should這個(gè)很傳神的詞.相反的,notification最大的特色就是不關(guān)心結(jié)果.所以notification往往用did這個(gè)詞匯.
-- 倆個(gè)模塊之間聯(lián)系不是很緊密,就用notificaiton傳值,例如多線程之間傳值用notification.
-- delegate 只是一種較為簡(jiǎn)單的回調(diào),而且主要用在一個(gè)模塊當(dāng)中,例如底層功能完成了,需要把一些值傳到上層去,就事先吧上層的函數(shù)通過(guò)delegate傳到底層,然后在底層call這個(gè)delegate,它們都在一個(gè)模塊中,完成一個(gè)功能,例如說(shuō) NavgationController 從 B 界面 到 A 點(diǎn)返回按鈕(調(diào)用popViewController方法)可以用delegate比較好
懶加載
- 懶加載,只在用到的時(shí)候才回去初始化.也可以理解成延時(shí)加載.我覺(jué)得最好也最簡(jiǎn)單的一個(gè)例子就是tableView中圖片的加載顯示了,一個(gè)延時(shí)加載,避免內(nèi)存過(guò)高,一個(gè)異步加載,避免線程堵塞提高用戶體驗(yàn)
OC有多繼承嗎,沒(méi)有的話可以用什么方法代替
- 多繼承即一個(gè)子類可以有多個(gè)父類,它繼承了多個(gè)父類的特性
- Object-C的類沒(méi)有多繼承,只有支持單繼承,如果要實(shí)現(xiàn)多繼承的話,可以通過(guò)類別和協(xié)議的方式來(lái)實(shí)現(xiàn)
- protocol(協(xié)議)可以實(shí)現(xiàn)多個(gè)接口,通過(guò)實(shí)現(xiàn)多個(gè)接口可以完成多繼承:
- Category(類別)一般使用分類,用Category去重寫(xiě)類的方法,僅對(duì)本Category有效,不會(huì)影響到其他類與原有類的關(guān)系
分別描述類別(categories)和延展(extensions)是什么?以及倆者的區(qū)別?繼承和類別在實(shí)現(xiàn)中有何區(qū)別?為什么category只能為對(duì)象添加方法,卻不能添加成員變量
- 類別:在沒(méi)有原類.m文件的基礎(chǔ)上,給該類添加方法;
- 延展: 一種特殊的類別,主要在一個(gè)類的.m文件里聲明和實(shí)現(xiàn)延展的作用,就是給某個(gè)類添加私有方法和私有變量.
** 倆個(gè)的區(qū)別: **
-延展可以添加屬性并且他添加的方法是必須要實(shí)現(xiàn)的.延展可以認(rèn)為是一個(gè)私有的類目
-類別可以再不知道,不改變?cè)瓉?lái)代碼的情況下往里面添加新的方法,只能添加,不能刪除 - 并且如果類別和原來(lái)類中的方法產(chǎn)生名稱沖突,那么類別會(huì)覆蓋之前的防范,類別具有更高的優(yōu)先級(jí)
- 集成可以增加,修改刪除方法,添加屬性
- category 只能為對(duì)象添加方法,卻不能天啊及成員變量的原因:如果可以添加成員變量,添加的成員變量沒(méi)有辦法初始化
Object-C有是有方法嗎?私有變量呢?如果沒(méi)有的話,有沒(méi)有什么代替的方法?
- Objective-c類里面的方法只有倆種,靜態(tài)方法和實(shí)例方法,但是可以通過(guò)把方法的聲明和定義都放在.m文件中.在Objective-C中,所有實(shí)例變量默認(rèn)都是私有的,所有實(shí)例方法默認(rèn)都是公有的
include和#import的區(qū)別?#import與@class的區(qū)別
- import 指令是 Object-C針對(duì) #include 的改進(jìn)版本, #import 確保引用的文件只會(huì)被引用一次,這樣這不會(huì)陷入遞歸包含的問(wèn)題了
- import 與 @calss 二者的區(qū)別在于
-- import 會(huì)鏈入該頭文件的全部信息,包括實(shí)例變量和方法等;而@class只是告訴編譯器,其后面聲明的名稱是類的名稱,至于這些類是如何定義的,暫時(shí)不用考慮
-- 在頭文件中一般使用@class來(lái)聲明這個(gè)名稱是類的名稱,不需要知道其內(nèi)部的實(shí)體變量和方法
-- 在實(shí)現(xiàn)類里面,因?yàn)闀?huì)用到這個(gè)引用類的內(nèi)部的實(shí)體變量和方法,所以需要用#import來(lái)包含這個(gè)被引用類的頭文件
-- 在編譯效率方面, 如果你有100個(gè)頭文件都#import了同一個(gè)文件,或者這些文件是依次應(yīng)用的,如A->B,B->C,C->D,這樣的引用關(guān)系,如果你的類有很多的話,這將會(huì)耗費(fèi)大量的時(shí)間.而@class則不會(huì)
-- 如果有循環(huán)依賴關(guān)系,如A->B,B->A,這樣的相互依賴關(guān)系,如果使用#import來(lái)相互包含,那么就會(huì)出現(xiàn)編譯錯(cuò)誤,如果使用@class在倆個(gè)類的頭文件中相互聲明,則不會(huì)有變異錯(cuò)誤的出現(xiàn).
淺拷貝和深拷貝
- 淺拷貝:只賦值指向?qū)ο蟮闹羔?而不復(fù)制引用對(duì)象本身.
- 深復(fù)制:復(fù)制引用對(duì)象本身.深復(fù)制就好理解理解了,內(nèi)存中存在了兩份獨(dú)立對(duì)象本身,當(dāng)修改A時(shí),A_copy不變.
類變量的@protected,@private,@public,@package聲明有什么含義?
變量的作用域不同
- @protected 該類和子類中訪問(wèn),是默認(rèn)的
- @private 只能在本類中訪問(wèn);
- @public 任何地方都能訪問(wèn)
- @package 本包內(nèi)使用,跨包不能使用
Objective-C和C,C++之間的聯(lián)系和區(qū)別
- Objective-C和C++都是C的面向?qū)ο蟮某?/li>
- Object與C++的區(qū)別主要點(diǎn):Object_C是完全動(dòng)態(tài)的,支持在運(yùn)行時(shí)動(dòng)態(tài)類型決議,動(dòng)態(tài)綁定以及動(dòng)態(tài)轉(zhuǎn)載;而C++是部分動(dòng)態(tài)的,編譯時(shí)靜態(tài)綁定,通過(guò)嵌入類(多重集成)和虛函數(shù)(虛表)來(lái)模擬實(shí)現(xiàn)
- Objective-C在語(yǔ)言層次上辭職動(dòng)態(tài)消息轉(zhuǎn)發(fā),其消息發(fā)送語(yǔ)法為[object function];而且C++ 為 objec->function(),兩者的語(yǔ)義也不同,在Objective-C里是發(fā)送消息到一個(gè)對(duì)象上,至于這個(gè)對(duì)象能不能響應(yīng)消息以及是響應(yīng)還是轉(zhuǎn)發(fā)消息都不會(huì)crash;而在C++里是說(shuō)對(duì)象進(jìn)行了某個(gè)操作,如果對(duì)象沒(méi)有這個(gè)操作的話,要么編譯會(huì)報(bào)錯(cuò)(靜態(tài)綁定),要么程序會(huì)crash掉的 (動(dòng)態(tài)綁定).
目標(biāo)-動(dòng)作機(jī)制
- 目標(biāo)是動(dòng)作消息的接收者,一個(gè)控件,或者更為常見(jiàn)的是他的單元,以插座變量的形式保持其動(dòng)作消息的目標(biāo).
- 動(dòng)作是控件發(fā)送給目標(biāo)的消息,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動(dòng)作而實(shí)現(xiàn)的方法.程序需要某些機(jī)制來(lái)進(jìn)行事件和指令的翻譯.這個(gè)機(jī)制就是目標(biāo)-動(dòng)作機(jī)制.
Objective-C優(yōu)點(diǎn)和缺點(diǎn)
- 優(yōu)點(diǎn):1.Cateogiey.2.posing.3動(dòng)態(tài)識(shí)別4.指標(biāo)計(jì)算;5.彈性信息傳遞;6.不是一個(gè)過(guò)度復(fù)雜的C衍生語(yǔ)言;7.Objective-C與C++可混合編程
- 確定:1.不支持命名空間;2.不支持運(yùn)算符重載;3.不支持多重繼承;4使用動(dòng)態(tài)運(yùn)行類型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時(shí)優(yōu)化方法都用不到.(如內(nèi)聯(lián)函數(shù)等),性能低劣
C語(yǔ)言的函數(shù)調(diào)用和OC的消息機(jī)制有什么區(qū)別
- 對(duì)于C語(yǔ)言.函數(shù)的調(diào)用在編譯的時(shí)候會(huì)決定調(diào)用哪個(gè)函數(shù).編譯完成之后直接順序執(zhí)行
- OC的函數(shù)調(diào)用成為消息發(fā)送.屬于動(dòng)態(tài)調(diào)用過(guò)程.在編譯的時(shí)候并不能解決真正的調(diào)用哪個(gè)函數(shù)(事實(shí)證明在編譯階段,OC可以調(diào)用任何函數(shù),即使這個(gè)函數(shù)并未實(shí)現(xiàn),只要申請(qǐng)過(guò)就不會(huì)報(bào)錯(cuò),而C語(yǔ)言在編譯階段就會(huì)報(bào)錯(cuò)).只有在真正運(yùn)行的時(shí)候才會(huì)根據(jù)函數(shù)的名稱找到對(duì)應(yīng)的函數(shù)來(lái)調(diào)用.
什么是謂詞
謂詞就是通過(guò)NSPredicate給定的邏輯條件作為約束條件,完成對(duì)數(shù)據(jù)的篩選
// 定義謂詞對(duì)象,謂詞對(duì)象中包含了過(guò)濾條件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<%d", 30];
// 可以使用&&進(jìn)行多條件過(guò)濾
predicate= [NSPredicate preicateWithFormat:@"name='1'&&age > 40"];
array = [persons filteredArrayUsingPredicate:predicate];
// 包含語(yǔ)句的使用
predicate = [NSPredcate predicateWithFormat:@"self.nameIN{'1','2','3'}||sele.age IN{30,40}"]
/** 指定字符開(kāi)頭和指定字符結(jié)尾,是否包含指定字符 */
// name已a(bǔ)開(kāi)頭的
predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH'a'"];
// name 中包含字符a的
predicate = [NSPredicate redicateWithFormat:@"name Contains'a'"];
// like 進(jìn)行匹配多個(gè)字符
predicate = [NSPredicate predicateWithFormat:@"name like 's'"];
// ?代表一個(gè)字符,下面的查詢條件是:name中第二個(gè)字符是s的
predicate = [NSPredicate predicateWithFormat:@"name like '?s'"];
C與OC混用
- 處理.m可以識(shí)別C和OC,.mm可以識(shí)別c c++ oc 但是cpp只能用c/c++
atomic和nonatomic的區(qū)別
- atomic提供多線程安全,房子讀寫(xiě)未完成的時(shí)候被另外一個(gè)線程讀寫(xiě),造成數(shù)據(jù)錯(cuò)誤
- nonatomic在管理內(nèi)存的環(huán)境中,解析的訪問(wèn)器保留并自動(dòng)釋放返回值,若指定了nonatomic,那么訪問(wèn)器只是簡(jiǎn)單的返回這個(gè)值
常見(jiàn)的oc數(shù)據(jù)類型那些,和c的基本類型有啥區(qū)別
- 常見(jiàn)的:NSInteger CGFloat NSString NSNumber NSArray NSDate
- NSInteger 根據(jù)32或者64位系統(tǒng)確定本身是int還是long
- CGFloat根據(jù)32或者64位系統(tǒng)確定本身是float還是double
- NSString NSNumber NSArray NSDate 都是指針類型的對(duì)象,在堆中分配內(nèi)存,c語(yǔ)言中char int 等都是在棧中分配空間
id 和 nil 代表什么
- id 類型的指針可以指向任何OC對(duì)象
- nil 代表空值(空指針的值, 0)
nil和NULL的區(qū)別
- 從oc的官方語(yǔ)法上面看,nil標(biāo)識(shí)對(duì)象的指針即對(duì)象的引用為空
- null表示指向基礎(chǔ)數(shù)據(jù)類型變量即c語(yǔ)言變量的指針為空
- 在非arc中 倆個(gè)空可以互換,但是在arc中普通指針和對(duì)象引用被嚴(yán)格限制,不能互換
nil,Nil,NULL和NSNull區(qū)別 - nil和C語(yǔ)言的NULL相同,在objc/objc.h中定義.nil表示objective-C對(duì)象的值為空.在C語(yǔ)言中,指針的空值用NULL表示.在Objective-C中,nil對(duì)象調(diào)用任何方法表示什么也不執(zhí)行,也不會(huì)崩潰
- Nil:那么對(duì)于我們Objective-C開(kāi)發(fā)來(lái)說(shuō),Nil也就代表((void*)0).但是它是用來(lái)代表空類的,比如:Class myClass = Nil;
- NULL:在C語(yǔ)言中,NULL是無(wú)類型的,只是一個(gè)宏,它代表空.這就是在C/C++中的空指針.對(duì)于我們Objective-C開(kāi)發(fā)來(lái)說(shuō),NULL就表示((void*)0)
- NSNull:NSNull集成于NSObject的類型.它是很特殊的類,它表示是空,什么也不是儲(chǔ)存,但是它確是對(duì)象,只是一個(gè)占位對(duì)象.使用場(chǎng)景就不一樣了.比如說(shuō)服務(wù)端接口中讓我們?cè)谥禐榭盏臅r(shí),穿空.NSDictionry *parameter = @{@"arg1":@"value1",@"arg2",arg2.isEmpty?[NSNull null]:arg2};
*NULL,nil,Nil這三者對(duì)于Objective-C中值是一樣的,都是(void )0,那么為什么要區(qū)分,又與NSNull之間有什么區(qū)別 - NULL 是宏, 是對(duì)于C語(yǔ)言指針來(lái)使用的,表示空指針
- nil 是宏, 是對(duì)于Objective-C中的類而使用的,表示類指向空
- Nil 是宏,是對(duì)于Objective-C中的類而使用的,表示類指向空
- NSNull 是類類型, 是用于表示空的占位對(duì)象,與JS或者服務(wù)端的null類似的含義
像一個(gè)nil對(duì)象發(fā)送消息會(huì)發(fā)生什么?
- 像nil發(fā)送消息是完全有效的--只是在運(yùn)行的時(shí)候不會(huì)有任何的作用
- 如果一個(gè)方法返回值是一個(gè)對(duì)象,那么發(fā)送給nil的消息將返回0(nil)
- 如果方法返回值為指針類型,其指針大小為小于或者等于sizeof(void*),float,double,long double 或者 longlong的整型標(biāo)量, 發(fā)送給nil的消息將返回0(nil)
- 如果方法返回值為指針類型,其指針大小為小于或者等于sizeof(void*),float,double,long double或者long long 的整型標(biāo)量, 發(fā)送給nil的消息將返回0
如果方法返回值為結(jié)構(gòu)體,正如在《Mac OS X ABI 函數(shù)調(diào)用指南》,發(fā)送給nil的消息將返回0,結(jié)構(gòu)體中各個(gè)字段的值都是0.其他的結(jié)構(gòu)體數(shù)據(jù)類型將不是用0填充的 - 如果方法的返回值不是上述提到的幾種情況,那么發(fā)送給nil的消息的返回值將是未定義.self.和self->的區(qū)別
- self.是調(diào)用get或者set方法
- self是當(dāng)前本身, 是一個(gè)指向當(dāng)前對(duì)象的指針
- self->是直接訪問(wèn)成員變量
類方法和實(shí)例方法的本質(zhì)區(qū)別和聯(lián)系
_block/weak修飾符區(qū)別
- _block在arc和mrc環(huán)境下都能使用,可以修飾對(duì)象,也能修飾基本數(shù)據(jù)類型
- _weak只能在arc環(huán)境下使用,只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)
- _block對(duì)象可以在block中重新賦值, _weak不行
寫(xiě)一個(gè)NSString類的實(shí)現(xiàn)
NSString *str = [[NSString alloc]initWithCString:nullTerminatedCString encodeing:encoding];
為什么標(biāo)準(zhǔn)頭文件都有類似以下的結(jié)構(gòu)
ifndef __INCvx Worksh
define __INCvx Worksh
ifdef __cplusplus
ectern "C"{
endif
ifdef __cplusplus
}
endif
endif
顯然,頭文件中的編譯宏#ifndef INCvxWorksh,#define INCvxWorksh,#endif 的作用是防止該頭文件唄重復(fù)引用
init和intwithobject區(qū)別(語(yǔ)法)
- 后者給屬性賦值
@property的本質(zhì)是什么?ibar,getter,setter是如何生成并添加到這個(gè)類中的
@property的本質(zhì):
@property = ivar(實(shí)例變量) + getter (取方法) + setter(存方法)
屬性(peoperty)兩大概念:
ivar(實(shí)例變量),存取方法(access method = getter + setter)
ivar,getter,setter如何生成并添加到類中:
這是編譯器自動(dòng)合成的,通過(guò)@synthesize關(guān)鍵字指定,若不指定,默認(rèn)為這是編譯器自動(dòng)合成的,通過(guò)@synthesize關(guān)鍵字指定,若不指定,默認(rèn)為@shnthesize propertyName = _propertyName;若手動(dòng)實(shí)現(xiàn)了getter/setter方法,則不會(huì)自動(dòng)合成.
現(xiàn)在編譯器已經(jīng)默認(rèn)為我們添加@synthesize propertyName = propertyName;因此不再需要手動(dòng)添加,除非你真的要改變成員變量
生成getter方法時(shí),會(huì)判斷當(dāng)前屬性名是否有,比如聲明屬性@property(nonatiomic,copy) NSString *_name; 那么所生成的成員變量就會(huì)變成name,如果我們要手動(dòng)生成getter方法,就要判斷是否以開(kāi)頭了.不過(guò),命名都要有規(guī)范,是不允許色林屬性是使用開(kāi)頭的,不規(guī)范的命名,在使用runtime的時(shí)候,會(huì)帶來(lái)很多不方便
這個(gè)寫(xiě)法會(huì)出什么問(wèn)題:@property(copy)NSMutableArray *array;
- 沒(méi)有指明未nonatiomic,因此就是atomic原子操作,會(huì)影響性能.該屬性使用同步鎖,會(huì)在創(chuàng)建時(shí)生成一些額外的代碼用于幫助編寫(xiě)多線程程序,這會(huì)帶來(lái)性能問(wèn)題,通過(guò)聲明nonatomic可以節(jié)省這些雖然很小但是不必要的額外開(kāi)銷.在我們的應(yīng)用程序中,幾乎都是使用nonatiomic來(lái)聲明的,因?yàn)槭褂胊tomic并不能保證絕對(duì)的線程安全,對(duì)于要絕對(duì)保證線程安全的操作,還需要使用更高級(jí)的方式來(lái)處理,比如NSSpinLock,@syncronized等
- 因?yàn)槭褂玫氖?copy,所得到的實(shí)際是NSArray類型,它是不可變的,若在使用中使用了增,刪,改操作,就會(huì)crash
@protocol和category中如何使用@property
- 在protocol中使用@property只會(huì)生成setter和getter方法聲明,我們使用屬性的目的是希望遵守我協(xié)議的對(duì)象能實(shí)現(xiàn)該屬性
- category 使用@property也只是會(huì)生成stter和getter方法的聲明,如果我們真的需要給category增加屬性的實(shí)現(xiàn),需要借助于運(yùn)行時(shí)的兩個(gè)函數(shù)
-- objc_setAssociatedObject
-- objc_getAssociatedObject
@property中有哪些屬性關(guān)鍵字
- 原子性(atomic, nonationmic)
- 讀寫(xiě)(readwrite, redonly)
- 內(nèi)存管理(assign,strong,weak,unsafe_unretaied,copy)
- getter, setter
isa指針問(wèn)題
- isa: 是一個(gè)Calss類型的指針,每個(gè)是你對(duì)象有個(gè)isa的指針,他指向?qū)ο蟮念?而Class里也有個(gè)isa的指針,指向meteCalss(元類).元類保存了類方法的李彪.當(dāng)類方法被調(diào)用時(shí),先會(huì)從本身查找類方法的實(shí)現(xiàn),如果沒(méi)有,元類會(huì)先從他父類查找該方法.同時(shí)注意的是:元類(meteCalss)也是類,它也是對(duì)象.元類也有isa指針,它的isa指針最終指向一個(gè)根元類(root meteClass).根元類的isa指向本身,這樣就行程了一個(gè)封閉的內(nèi)循環(huán)
如何訪問(wèn)并修改一個(gè)類的私有屬性
- 一種是通過(guò)KVC獲取
- 通過(guò)runtime訪問(wèn)并修改私有屬性
如何為Class定義一個(gè)對(duì)外只讀對(duì)內(nèi)可讀寫(xiě)的屬性
在頭文件中將屬性定義為readonly,在.m文件中將屬性新重新定義readwrite
Objective-C中,meta-Class指的什么?
meta-class是Class對(duì)象的類,為這個(gè)Class類儲(chǔ)存類方法,當(dāng)一個(gè)類發(fā)送消息時(shí),就會(huì)去這個(gè)類對(duì)應(yīng)的metaClass中查找那個(gè)消息,每個(gè)Class都有不同的meta-class,所有的meta-class都使用基類的meta-class(假如類繼承NSObject,那么他對(duì)應(yīng)的meta-class也是NSObject)作為他們的類
Objective-C的class是如何實(shí)現(xiàn)的,selector是如何轉(zhuǎn)換成C語(yǔ)言的函數(shù)調(diào)用的
- 當(dāng)一個(gè)類被正確的編譯過(guò)后,在這個(gè)編譯成功的類里面,存在一個(gè)變量用于保存這個(gè)類的信息.我們可以通過(guò)[NSClassFromString]或[obj class].這樣的機(jī)制允許我們?cè)诔绦驁?zhí)行的過(guò)程當(dāng)中,可以Class來(lái)得到對(duì)象的類,也可以在程序執(zhí)行的階段動(dòng)態(tài)的生成一個(gè)再編譯階段無(wú)法確定的一個(gè)對(duì)象.(isa指針)
- @selector()基本可以等同C語(yǔ)言的中函數(shù)指針,只不過(guò)C語(yǔ)言中,可以把函數(shù)名直接賦給一個(gè)函數(shù)指針,而Object-C的類不能直接應(yīng)用函數(shù)指針,這樣只能做一個(gè)@selector語(yǔ)言來(lái)取.
@interface foo
- (int)add:int val;
@end
SEL class_func; //定義一個(gè)類方法指針
class_func = @selector(add:int);
- @selector 是查找當(dāng)前類的方法, 而[object @selector(方法名:方法參數(shù)...)];是取object對(duì)應(yīng)類的相應(yīng)方法
- 查詢類方法時(shí),除了方法名,方法參數(shù)也查詢條件之一
- 可以用字符串來(lái)找方法 SEL 變量名 = NSSelectorFromString(方法名字的字符串);
- 可以運(yùn)行中用SEL變量反向查出方法名字字符串.NSString *變量名 = NSStringFromSelect(SEL參數(shù))
- 取到Selector的值以后,執(zhí)行seletor.SEL變量執(zhí)行.用performSelecor方法來(lái)執(zhí)行.[對(duì)象 performSelector:SEL變量 withObjet:參數(shù)1 withObject:參數(shù)2];
對(duì)于語(yǔ)言NSString *obj = [[NSData alloc] init]; 編譯時(shí)和運(yùn)行時(shí) obj 分別是什么類型
- 編譯時(shí)是NSString 類型, 運(yùn)行時(shí)是NSData類型
@synthesize和@dynamic分別什么作用
- @property有倆個(gè)對(duì)應(yīng)的詞,一個(gè) 是 @synthesize,一個(gè)是@dynamic.如果@synthesize 和 @dynamic都沒(méi)寫(xiě),那么默認(rèn)的就是@synthesize var = _var;
-@synthesieze 的語(yǔ)義是如果你沒(méi)有手動(dòng)實(shí)現(xiàn) setter 方法和 getter 方法, 那么編譯器會(huì)自動(dòng)為你加上這個(gè)倆個(gè)方法. - @dynamic 告訴編譯器:屬性的setter與getter方法由用戶自己實(shí)現(xiàn),不自動(dòng)生成.(當(dāng)然對(duì)于 readonly 的屬性只需提供getter即可).假如一個(gè)屬性被聲明為 @dynamic var,然后你沒(méi)有提供 @setter 方法和 @getter 方法,編譯的時(shí)候沒(méi)有問(wèn)題,但是當(dāng)程序運(yùn)行到 instance.var = someVar, 由于缺 setter 方法會(huì)導(dǎo)致程序崩潰; 或者當(dāng)運(yùn)行到 someVar = var 時(shí),由于缺getter方法同樣會(huì)導(dǎo)致崩潰.編譯時(shí)沒(méi)有問(wèn)題,運(yùn)行時(shí)才執(zhí)行相應(yīng)的方法,這就是所謂的動(dòng)態(tài)綁定.
NSString的時(shí)候用copy和strong的區(qū)別
OC中NSString為不可變字符串的時(shí)候,copy和strong都是只分配一次內(nèi)存,但是如果用copy的時(shí)候,需要先判斷字符串時(shí)候是不可變字符串,如果是不可變字符串,就不再分配控件,如果是可變字符串才分配控件.如果程序中用到NSString的地方特別多,每一次都要先進(jìn)行判斷就會(huì)消耗性能,影響用戶體驗(yàn),用strong就不會(huì)再進(jìn)行變短,所以,不可變字符串都可以直接用strong.
NSArray,NSSet,NSDictionary,與NSMutableArray,NSMutableSet, NSMutableDictionary的特性和作用(遇到copy修飾產(chǎn)生變化)
特性:
- NSArray 表示不可變的數(shù)組, 是有序元數(shù)集,只能儲(chǔ)存對(duì)象類型,可通過(guò)索引直接訪問(wèn)元數(shù),而且元數(shù)類型可以不一樣,但是不能進(jìn)行增刪改,NSMutableArray是可變數(shù)組,能進(jìn)行增刪改.通過(guò)索引查詢值很快,但是插入,刪除,等效率很低
- NSSset標(biāo)識(shí)不可變集合,具有穩(wěn)定性,互異性,無(wú)序性的特點(diǎn),只能訪問(wèn)而不嗯呢修改集合:NSMutableSet可變集合,可以對(duì)集合進(jìn)行增刪改.集合通過(guò)值查詢很快,插入,刪除操作極快
- NSDictionary 表示不可變字典,具有無(wú)序性的特點(diǎn),每個(gè)key對(duì)應(yīng)的值是唯一的,可通過(guò)key直接取值,NSMutableDictionary表示可變字典,能對(duì)字典進(jìn)行增刪改,通過(guò)key查詢插入和刪除都很快.
作用 - 數(shù)組用于處理一組有序的數(shù)據(jù)集,比如常用的列表的dataSource要求有序,可通過(guò)索引直接訪問(wèn),效率高
- 集合要求具有確定性,互異性,無(wú)序性,在iOS開(kāi)發(fā)中是比較少使用到的,筆者也不清楚如何說(shuō)明其作用
- 字典是鍵值對(duì)數(shù)據(jù)集,操作字典效率極高,時(shí)間復(fù)雜度為常量,但是值是無(wú)序的,在iOS中,常見(jiàn)的JSON轉(zhuǎn)字典,字典轉(zhuǎn)模型就是之中的一種應(yīng)用.
請(qǐng)把字符串2015-04-10格式化日期轉(zhuǎn)換為NSDate類型
NSString *timeStr = @"2015-04-10";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd";
formatter.timeZone = [NSTimeZone defaultTimeZone];
NSDate *date = [formatter fateFromString:timeStr];
// 2015-04-09 16:00:00 + 0000
NSLog(@"%@", date);
在一個(gè)對(duì)象的方法里面:self.name=@object;和name=@object有什么不同
- 這是老生常談的話題了,實(shí)質(zhì)上就是問(wèn)setter方法賦值與成員變量賦值有什么不同.通過(guò)點(diǎn)語(yǔ)法self.name實(shí)質(zhì)上就是[self setName];兒name這里是成員變量,直接賦值
- 一般來(lái)說(shuō),在對(duì)象的方法里成員變量和方法都是可以訪問(wèn)的,我們通常會(huì)重寫(xiě)seter方法來(lái)執(zhí)行某些額外的工作.比如說(shuō),外部傳一個(gè)模型過(guò)來(lái),那么我會(huì)直接重寫(xiě)setter方法,當(dāng)模型傳過(guò)來(lái)時(shí),也就因?yàn)檫@數(shù)據(jù)發(fā)生了變化,那么視圖也需要更新顯示,則在賦值新模型的同時(shí)也在刷新UI.這樣也不用在額外去提供其他方法了
怎樣使用performSelector傳入3個(gè)以上參數(shù),其中一個(gè)為結(jié)構(gòu)體
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
因?yàn)橄到y(tǒng)提供的performSelector的api中,并沒(méi)有提供三個(gè)參數(shù).因此,我們只能傳數(shù)組或者字典,三十?dāng)?shù)組或者字典自有存入對(duì)象類型,而結(jié)構(gòu)體并不是對(duì)象類型,那怎么辦呢?沒(méi)有辦法,我們只能通過(guò)對(duì)象放入結(jié)構(gòu)最為屬性傳遞過(guò)去了
typedef struct HYBStruct {
int a;
int b;
} *my_struct;
@interface HYBObject : NSObject
@property (nonatomic, assign) my_struct arg3;
@property (nonatomic, copy) NSString *arg1;
@property (nonatomic, copy) NSString *arg2;
@end
@implementation HYBObject
// 在堆上分配內(nèi)存,我們要手動(dòng)釋放
- (void)dealloc {
free(self.arg3);
}
@end
測(cè)試:
my_struct str = (my_struct)(malloc(sizeof(my_struct)));
str->a = 1;
str->b = 2;
HYBObject *obj = [[HYBObject alloc] init];
obj.arg1 = @"arg1";
obj.arg2 = @"arg2";
obj.arg3 = str;
[self performSelector:@selector(call:) withObject:obj];
// 在回調(diào)時(shí)得到正確的數(shù)據(jù)
- (void)call:(HYBObject *)obj {
NSLog(@"%d %d", obj.arg3->a, obj.arg3->b);
}
objc中一個(gè)對(duì)象發(fā)送消息[obj foo]和objc_msgSend()函數(shù)之間有什么關(guān)系
實(shí)際上,編譯器在編譯的時(shí)候會(huì)轉(zhuǎn)換成objc_msgSedn,大概會(huì)像這樣:
(void(*))(id, SEL)
((void) objc_msgSend)
((id)obj, sel_registerName("foo"))
也就是說(shuō), [obj foo];在objc動(dòng)態(tài)編譯時(shí),會(huì)被轉(zhuǎn)換成:objc_msgSend(obj,@selector(foo));這樣的形式, 但是需要根據(jù)具體的參數(shù)類型返回值類型進(jìn)行相應(yīng)的類型轉(zhuǎn)換.
下面代碼輸出是什么
@implementation Son: Father
- (id)init {
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
結(jié)果:
NSStringFromClass([self class]) = Son
NSStringFromClass([super class]) = Son
解析:這個(gè)題目主要是考察關(guān)于Objective-C中對(duì)self和super的理解.我們都知道:self是類的隱藏參數(shù),指向當(dāng)前調(diào)用方法的這個(gè)類的實(shí)例.那么super呢,很多人會(huì)想當(dāng)然的認(rèn)為"super"和self類似,應(yīng)該是指向父類的指針吧!這是很普遍的一個(gè)誤區(qū).其實(shí)super是一個(gè) magic keyword,他的本質(zhì)是個(gè)編譯器標(biāo)識(shí)符,和self是指向同一個(gè)消息接受者!她們倆個(gè)的不同點(diǎn)在于:super告訴編譯器,調(diào)用class這個(gè)方法時(shí),要去父類的方法,而不是本類里面的.上面的例子不管調(diào)用[self class]還是[super class],接受消息的對(duì)象都是當(dāng)前 son *xxx 這個(gè)對(duì)象.當(dāng)使用self調(diào)用方法時(shí),會(huì)從當(dāng)前類的方法列表中開(kāi)始找,如果沒(méi)有,就從父類中再找;而當(dāng)使用super時(shí),則會(huì)從父類的方法列表中開(kāi)始找.然后調(diào)用父類的這個(gè)方法.
若一個(gè)類有實(shí)例變量NSString *_foo, 調(diào)用setValue:forkey:時(shí),可以foo還是_foo作為key
- 兩者都可以
什么時(shí)候使用NSMutableArray,什么時(shí)候使用NSArray
- 當(dāng)數(shù)組在程序運(yùn)行時(shí),需要不斷的變化,使用NSMutableArray,當(dāng)數(shù)組在初始化后,便不再改變的,使用NSArray.需要指出的是,使用NSArray只表明的是該數(shù)組在運(yùn)行的時(shí)候不會(huì)發(fā)生改變,即不能往NSAarray的數(shù)組里面新增和刪除元素,但不表明其數(shù)組內(nèi)的元素的內(nèi)容不能發(fā)生改變.NSArray是線程安全的,NSMutableArray不是線程安全的,多線程使用到NSMutableArray需要注意
類NSObject的哪些方法經(jīng)常被使用
- NSObject是Objective-C的基類,其由NSObject類以及一系列協(xié)議構(gòu)成.
- 其中類方法alloc,class,description 對(duì)象方法 init, dealloc, - performSelector:withObject:afterDelay:等經(jīng)常被使用
什么是簡(jiǎn)便構(gòu)造器
- 簡(jiǎn)便構(gòu)造方法一般由CocoaTouch框架提供,如NSNumber+numberWithBool + numberWithChar + numberWithDouble + numberWithFloat + numberWithInt
- Foundation 下大部分類均有簡(jiǎn)便構(gòu)造器方法,我們可以通過(guò)簡(jiǎn)便構(gòu)造方法,活的系統(tǒng)給我們創(chuàng)建好的對(duì)象,并且不需要手動(dòng)釋放
什么是構(gòu)造器方法,使用構(gòu)造器的特點(diǎn)
- 構(gòu)造方法是對(duì)象初始化并且實(shí)例的方法
- 一般構(gòu)造方法里對(duì)類進(jìn)行一些初始化操作,方法必須要init開(kāi)頭,接下來(lái)名稱要大寫(xiě),例如initWithName.initLayout
創(chuàng)建一個(gè)對(duì)象需要經(jīng)過(guò)哪三個(gè)步驟
- 開(kāi)辟內(nèi)存空間
- 初始化參數(shù)
- 返回內(nèi)存地址值
get方法的作用是什么
- 為調(diào)用者返回對(duì)象內(nèi)部的成員變量
set方法的作用是什么,set的好處
- 為調(diào)用者設(shè)置對(duì)象內(nèi)部的成員變量
好處 - 在成員變量的變化時(shí)候可以在方法里面做相應(yīng)的操作,無(wú)需寫(xiě)多余的方法
- 不然數(shù)據(jù)暴露在外,保證了數(shù)據(jù)的安全性
- 對(duì)這是的數(shù)據(jù)進(jìn)行過(guò)濾
結(jié)構(gòu)體當(dāng)中不能定義OC對(duì)象嗎
- 不能,因?yàn)榻Y(jié)構(gòu)體當(dāng)中只能是類型的聲明不能進(jìn)行分配空間
點(diǎn)語(yǔ)法本質(zhì)是什么,寫(xiě)一個(gè)點(diǎn)語(yǔ)法的例子,并寫(xiě)上注釋
- 點(diǎn)語(yǔ)法的本質(zhì)是方法的調(diào)用, 而不是訪問(wèn)成員變量, 當(dāng)使用點(diǎn)語(yǔ)法時(shí),編譯器會(huì)自動(dòng)展開(kāi)成相應(yīng)的方法.切記點(diǎn)語(yǔ)法的本質(zhì)是轉(zhuǎn)換成相應(yīng)的set和get方法,如果沒(méi)有set和get方法,則不能使用點(diǎn)語(yǔ)法.
- 例如有一個(gè)Person類 通過(guò)@property定義了name和age屬性,在提供一個(gè)run方法.
Person *person = [Person new];
person.name = @"itcast";調(diào)用了person的setName方法
int age - person.age; // 調(diào)用了person的age方法
person.run // 調(diào)用了person的run方法
id類型是什么,instancetype是什么,有什么區(qū)別
- id類型:萬(wàn)能指針,能作為參數(shù),防范的返回類型
- isntancetype:只能作為方法的范圍類型,并且返回的類型是當(dāng)前定義類的類型.
成員變量名的命名以下劃線開(kāi)頭的好處
- 與get方法的方法名區(qū)分開(kāi)來(lái)
- 可以和一些其他的局部變量分開(kāi)來(lái),下劃線開(kāi)頭的變量,通常都是類的成員變量
下面這段代碼有什么問(wèn)題
@implementation Person
- (void)setAge:(int)newAge {
self.age = newAge;
}
@end
這個(gè)會(huì)造成死循環(huán),點(diǎn)語(yǔ)法是方法的調(diào)用,會(huì)一直走這個(gè)方法,_age = age;書(shū)寫(xiě)也不規(guī)范應(yīng)該是吧newAge改成age
截取字符串"20|http://www.bai.com"中,"I"字符前面和后面的數(shù)據(jù),分別輸出他們
NSString *str = @"20|http://ww.baidu.com";
NSSArray *array = [str componentsSeparatedByString:@"|"]:
// 打印前后的數(shù)據(jù)輸出
for (int i = 0; i <array.count; i ++) {
NSLog(@"%d=%@", i,[array objectAtInde:i]);
}
寫(xiě)一個(gè)完整的代碼,包括聲明,實(shí)現(xiàn)
// 創(chuàng)建
@protocol MyDelete
@required
- (void)eat:(NSString *)foodName;
@optional
- (void)run;
// 聲明
@interface person : NSObject<MyDelagete>
@end
// 實(shí)現(xiàn)
@implement person
- (void)eat:(NSString *)foodName {
NSLog(@"吃%@",foodName);
}
- (void)run {
NSLog(@"run!");
}
@end
isKindOfClass,isMemberOfClass,selector作用分別是什么
- isKindOfClass, 作用是,某個(gè)對(duì)象屬于某個(gè)類型或者繼承自某類型
- isMemberOfClass:某個(gè)對(duì)象確切屬于某個(gè)類型
- selector:通過(guò)方法名,獲取在內(nèi)存中函數(shù)的入口地址
請(qǐng)分別寫(xiě)出SEL,id,@的意思
- SEL是"selector"的一個(gè)類型,標(biāo)識(shí)一個(gè)方法的名字---就是一個(gè)方法的入口地址
- id是一個(gè)執(zhí)行任何一個(gè)集成了Object(或者NSObject)類的對(duì)象.需要注意的是id是一個(gè)指針,所以在使用id的時(shí)候不需要添加*
- @是OC中的指令符號(hào)
unsigned int 和 int 有什么區(qū)別.假設(shè)int長(zhǎng)度為65535,請(qǐng)寫(xiě)出unsigned int 與int 的取值范圍
- int:基本整型,當(dāng)字節(jié)數(shù)為2事取值范圍為-32768~32767, 當(dāng)字節(jié)數(shù)為4時(shí),取值范圍負(fù)的2的31次方到2的31次方減一
unsigned int: 無(wú)符號(hào)基本整型,當(dāng)字節(jié)數(shù)為2時(shí)取值范圍為0~65535, 當(dāng)字節(jié)數(shù)為4時(shí),取值范圍為0到2的32次方減一
Foundation對(duì)象與Core Foundation 對(duì)象有什么區(qū)別
- Foundation對(duì)象是OC的, Core Foundation 對(duì)象是C對(duì)象
- 數(shù)據(jù)類型之間的轉(zhuǎn)換
-- ARC:bridge_retained(持有對(duì)象所有權(quán),F->CF),bridge_transfer(釋放對(duì)象所有權(quán)CF->F)
-- 非ARC:__bridge
編寫(xiě)一個(gè)函數(shù),實(shí)現(xiàn)遞歸刪除地址路徑下的所有文件
+ (void)deleteFiles:(NSString *)path;{
// 1. 判斷是文件還是目錄
NSFileManager * fileManger = [NSFileManager defaultManager];
BOOL isDir = NO;
BOOL isExist = [fileManger fileExistsAtPath:path isDirectory:&isDir];
if (isExist) {
// 2. 判斷是不是目錄
if (isDir) {
NSArray * dirArray = [fileManger contentsOfDirectoryAtPath:path error:nil];
NSString * subPath = nil;
for (NSString * str in dirArray) {
subPath = [path stringByAppendingPathComponent:str];
BOOL issubDir = NO;
[fileManger fileExistsAtPath:subPath isDirectory:&issubDir];
[self deleteFiles:subPath];
}
}else{
NSLog(@"%@",path);
[manager removeItemAtPath:filePath error:nil];
}
}else{
NSLog(@"你打印的是目錄或者不存在");
}
}