1.設(shè)計(jì)模式是什么驻子? 你知道哪些設(shè)計(jì)模式灿意,并簡要敘述?
設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn)崇呵,就是用比較成熟的邏輯去處理某一種類型的事情缤剧。
1). MVC模式:Model View Control,把模型 視圖 控制器 層進(jìn)行解耦合編寫域慷。
2). MVVM模式:Model View ViewModel 把模型 視圖 業(yè)務(wù)邏輯 層進(jìn)行解耦和編寫荒辕。
3). 單例模式:通過static關(guān)鍵詞,聲明全局變量犹褒。在整個進(jìn)程運(yùn)行期間只會被賦值一次抵窒。
4). 觀察者模式:KVO是典型的通知模式,觀察某個屬性的狀態(tài)叠骑,狀態(tài)發(fā)生變化時(shí)通知觀察者李皇。
5). 委托模式:代理+協(xié)議的組合。實(shí)現(xiàn)1對1的反向傳值操作宙枷。
6). 工廠模式:通過一個類方法掉房,批量的根據(jù)已有模板生產(chǎn)對象。
MVC 和 MVVM 的區(qū)別
1). MVVM是對胖模型進(jìn)行的拆分慰丛,其本質(zhì)是給控制器減負(fù)卓囚,將一些弱業(yè)務(wù)邏輯放到VM中去處理。
2). MVC是一切設(shè)計(jì)的基礎(chǔ)诅病,所有新的設(shè)計(jì)模式都是基于MVC進(jìn)行的改進(jìn)哪亿。
#import跟 #include 有什么區(qū)別,@class呢贤笆,#import<> 跟 #import””有什么區(qū)別蝇棉?
答:
1). #import是Objective-C導(dǎo)入頭文件的關(guān)鍵字,#include是C/C++導(dǎo)入頭文件的關(guān)鍵字芥永,使用#import頭文件會自動只導(dǎo)入一次银萍,不會重復(fù)導(dǎo)入。
2). @class告訴編譯器某個類的聲明恤左,當(dāng)執(zhí)行時(shí)贴唇,才去查看類的實(shí)現(xiàn)文件搀绣,可以解決頭文件的相互包含。
3). #import<>用來包含系統(tǒng)的頭文件戳气,#import””用來包含用戶頭文件链患。
frame 和 bounds 有什么不同?
frame指的是:該view在父view坐標(biāo)系統(tǒng)中的位置和大小瓶您。(參照點(diǎn)是父view的坐標(biāo)系統(tǒng))
bounds指的是:該view在本身坐標(biāo)系統(tǒng)中的位置和大小麻捻。(參照點(diǎn)是本身坐標(biāo)系統(tǒng))
Objective-C的類可以多重繼承么?可以實(shí)現(xiàn)多個接口么呀袱?Category是什么贸毕?重寫一個類的方式用繼承好還是分類好?為什么夜赵?
答:Objective-C的類不可以多重繼承明棍;可以實(shí)現(xiàn)多個接口(協(xié)議);Category是類別寇僧;一般情況用分類好摊腋,用Category去重寫類的方法,僅對本Category有效嘁傀,不會影響到其他類與原有類的關(guān)系兴蒸。
@property 的本質(zhì)是什么?ivar细办、getter橙凳、setter 是如何生成并添加到這個類中的
@property 的本質(zhì)是什么?
@property = ivar + getter + setter;
“屬性” (property)有兩大概念:ivar(實(shí)例變量)笑撞、getter+setter(存取方法)
“屬性” (property)作為 Objective-C 的一項(xiàng)特性岛啸,主要的作用就在于封裝對象中的數(shù)據(jù)。 Objective-C 對象通常會把其所需要的數(shù)據(jù)保存為各種實(shí)例變量娃殖。實(shí)例變量一般通過“存取方法”(access method)來訪問。其中议谷,“獲取方法” (getter)用于讀取變量值炉爆,而“設(shè)置方法” (setter)用于寫入變量值。
@property中有哪些屬性關(guān)鍵字卧晓?/ @property 后面可以有哪些修飾符芬首?
屬性可以擁有的特質(zhì)分為四類:
1.原子性--- nonatomic 特質(zhì)
2.讀/寫權(quán)限---readwrite(讀寫)、readonly (只讀)
3.內(nèi)存管理語義---assign逼裆、strong郁稍、 weak、unsafe_unretained胜宇、copy
4.方法名---getter= 耀怜、setter=
5.不常用的:nonnull,null_resettable,nullable
屬性關(guān)鍵字 readwrite恢着,readonly,assign财破,retain掰派,copy,nonatomic 各是什么作用左痢,在那種情況下用靡羡?
答:
1). readwrite 是可讀可寫特性。需要生成getter方法和setter方法俊性。
2). readonly 是只讀特性略步。只會生成getter方法,不會生成setter方法定页,不希望屬性在類外改變趟薄。
3). assign 是賦值特性。setter方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí),assign用于基本數(shù)據(jù)類型拯勉。
4). retain(MRC)/strong(ARC) 表示持有特性竟趾。setter方法將傳入?yún)?shù)先保留,再賦值宫峦,傳入?yún)?shù)的retaincount會+1岔帽。
5). copy 表示拷貝特性。setter方法將傳入對象復(fù)制一份导绷,需要完全一份新的變量時(shí)犀勒。
6). nonatomic 非原子操作。決定編譯器生成的setter和getter方法是否是原子操作妥曲,atomic表示多線程安全贾费,一般使用nonatomic,效率高檐盟。
什么情況使用 weak 關(guān)鍵字褂萧,相比 assign 有什么不同?
1.在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時(shí)候,往往要通過讓其中一端使用 weak 來解決,比如: delegate 代理屬性葵萎。
2.自身已經(jīng)對它進(jìn)行一次強(qiáng)引用,沒有必要再強(qiáng)引用一次,此時(shí)也會使用 weak,自定義 IBOutlet 控件屬性一般也使用 weak导犹;當(dāng)然,也可以使用strong羡忘。
IBOutlet連出來的視圖屬性為什么可以被設(shè)置成weak?
因?yàn)楦缚丶膕ubViews數(shù)組已經(jīng)對它有一個強(qiáng)引用谎痢。
不同點(diǎn):
assign 可以用非 OC 對象,而 weak 必須用于 OC 對象卷雕。
weak 表明該屬性定義了一種“非擁有關(guān)系”节猿。在屬性所指的對象銷毀時(shí),屬性值會自動清空(nil)漫雕。
怎么用 copy 關(guān)鍵字滨嘱?
用途:
1. NSString峰鄙、NSArray、NSDictionary 等等經(jīng)常使用copy關(guān)鍵字九孩,是因?yàn)樗麄冇袑?yīng)的可變類型:NSMutableString先馆、NSMutableArray、NSMutableDictionary躺彬;
2. block 也經(jīng)常使用 copy 關(guān)鍵字煤墙。
說明:
block 使用 copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內(nèi)部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).在 ARC 中寫不寫都行:對于 block 使用 copy 還是 strong 效果是一樣的,但寫上 copy 也無傷大雅宪拥,還能時(shí)刻提醒我們:編譯器自動對 block 進(jìn)行了 copy 操作仿野。如果不寫 copy ,該類的調(diào)用者有可能會忘記或者根本不知道“編譯器會自動對 block 進(jìn)行了 copy 操作”她君,他們有可能會在調(diào)用之前自行拷貝屬性值脚作。這種操作多余而低效。
用@property聲明的 NSString / NSArray / NSDictionary 經(jīng)常使用 copy 關(guān)鍵字缔刹,為什么球涛?如果改用strong關(guān)鍵字,可能造成什么問題校镐?
答:用 @property 聲明 NSString亿扁、NSArray、NSDictionary 經(jīng)常使用 copy 關(guān)鍵字鸟廓,是因?yàn)樗麄冇袑?yīng)的可變類型:NSMutableString从祝、NSMutableArray、NSMutableDictionary,他們之間可能進(jìn)行賦值操作(就是把可變的賦值給不可變的),為確保對象中的字符串值不會無意間變動磁奖,應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份。
1. 因?yàn)楦割愔羔樋梢灾赶蜃宇悓ο?使用 copy 的目的是為了讓本對象的屬性不受外界影響,使用 copy 無論給我傳入是一個可變對象還是不可對象,我本身持有的就是一個不可變的副本换可。
2. 如果我們使用是 strong ,那么這個屬性就有可能指向一個可變對象,如果這個可變對象在外部被修改了,那么會影響該屬性。
//總結(jié):使用copy的目的是,防止把可變類型的對象賦值給不可變類型的對象時(shí),可變類型對象的值發(fā)送變化會無意間篡改不可變類型對象原來的值契讲。
淺拷貝和深拷貝的區(qū)別?
答:
淺拷貝:只復(fù)制指向?qū)ο蟮闹羔樀挡#粡?fù)制引用對象本身怀泊。
深拷貝:復(fù)制引用對象本身茫藏。內(nèi)存中存在了兩份獨(dú)立對象本身误趴,當(dāng)修改A時(shí),A_copy不變务傲。
系統(tǒng)對象的 copy 與 mutableCopy 方法
不管是集合類對象(NSArray凉当、NSDictionary枣申、NSSet ... 之類的對象),還是非集合類對象(NSString, NSNumber ... 之類的對象)看杭,接收到copy和mutableCopy消息時(shí)忠藤,都遵循以下準(zhǔn)則:
1. copy 返回的是不可變對象(immutableObject);如果用copy返回值調(diào)用mutable對象的方法就會crash楼雹。
2. mutableCopy 返回的是可變對象(mutableObject)模孩。
一、非集合類對象的copy與mutableCopy
? 在非集合類對象中贮缅,對不可變對象進(jìn)行copy操作榨咐,是指針復(fù)制,mutableCopy操作是內(nèi)容復(fù)制谴供;
? 對可變對象進(jìn)行copy和mutableCopy都是內(nèi)容復(fù)制块茁。用代碼簡單表示如下:
NSString *str = @"hello word!";
NSString *strCopy = [str copy] // 指針復(fù)制,strCopy與str的地址一樣
NSMutableString *strMCopy = [str mutableCopy] // 內(nèi)容復(fù)制桂肌,strMCopy與str的地址不一樣
NSMutableString *mutableStr = [NSMutableString stringWithString: @"hello word!"];
NSString *strCopy = [mutableStr copy] // 內(nèi)容復(fù)制
NSMutableString *strMCopy = [mutableStr mutableCopy] // 內(nèi)容復(fù)制
二数焊、集合類對象的copy與mutableCopy (同上)
? 在集合類對象中,對不可變對象進(jìn)行copy操作崎场,是指針復(fù)制佩耳,mutableCopy操作是內(nèi)容復(fù)制;
? 對可變對象進(jìn)行copy和mutableCopy都是內(nèi)容復(fù)制照雁。但是:集合對象的內(nèi)容復(fù)制僅限于對象本身蚕愤,對集合內(nèi)的對象元素仍然是指針復(fù)制。(即單層內(nèi)容復(fù)制)
? ? NSArray *arr = @[@[@"a", @"b"], @[@"c", @"d"];
? ? NSArray *copyArr = [arr copy]; // 指針復(fù)制
? ? NSMutableArray *mCopyArr = [arr mutableCopy]; //單層內(nèi)容復(fù)制
? ? NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
? ? NSArray *copyArr = [mutableArr copy]; // 單層內(nèi)容復(fù)制
? ? NSMutableArray *mCopyArr = [mutableArr mutableCopy]; // 單層內(nèi)容復(fù)制
【總結(jié)一句話】:
只有對不可變對象進(jìn)行copy操作是指針復(fù)制(淺復(fù)制)饺蚊,其它情況都是內(nèi)容復(fù)制(深復(fù)制)萍诱!
這個寫法會出什么問題:@property (nonatomic, copy) NSMutableArray *arr;
問題:添加,刪除,修改數(shù)組內(nèi)的元素的時(shí)候,程序會因?yàn)檎也坏綄?yīng)的方法而崩潰。
//如:-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fcd1bc30460
// copy后返回的是不可變對象(即 arr 是 NSArray 類型污呼,NSArray 類型對象不能調(diào)用 NSMutableArray 類型對象的方法)
原因:是因?yàn)?copy 就是復(fù)制一個不可變 NSArray 的對象裕坊,不能對 NSArray 對象進(jìn)行添加/修改。
如何讓自己的類用 copy 修飾符燕酷?如何重寫帶 copy 關(guān)鍵字的 setter籍凝?
若想令自己所寫的對象具有拷貝功能,則需實(shí)現(xiàn) NSCopying 協(xié)議苗缩。如果自定義的對象分為可變版本與不可變版本饵蒂,那么就要同時(shí)實(shí)現(xiàn) NSCopying 與 NSMutableCopying 協(xié)議。
具體步驟:
1. 需聲明該類遵從 NSCopying 協(xié)議
2. 實(shí)現(xiàn) NSCopying 協(xié)議的方法酱讶。
// 該協(xié)議只有一個方法:
- (id)copyWithZone:(NSZone *)zone;
// 注意:使用 copy 修飾符退盯,調(diào)用的是copy方法,其實(shí)真正需要實(shí)現(xiàn)的是 “copyWithZone” 方法。
寫一個 setter 方法用于完成 @property (nonatomic, retain) NSString *name渊迁,寫一個 setter 方法用于完成 @property (nonatomic, copy) NSString *name
答:
// retain
- (void)setName:(NSString *)str {
? [str retain];
? [_name release];
? _name = str;
}
// copy
- (void)setName:(NSString *)str {
? id t = [str copy];
? [_name release];
? _name = t;
}
@synthesize 和 @dynamic 分別有什么作用慰照?
@property有兩個對應(yīng)的詞,一個是@synthesize(合成實(shí)例變量)琉朽,一個是@dynamic毒租。
如果@synthesize和@dynamic都沒有寫,那么默認(rèn)的就是 @synthesize var = _var;
// 在類的實(shí)現(xiàn)代碼里通過 @synthesize 語法可以來指定實(shí)例變量的名字箱叁。(@synthesize var = _newVar;)
1. @synthesize 的語義是如果你沒有手動實(shí)現(xiàn)setter方法和getter方法墅垮,那么編譯器會自動為你加上這兩個方法。
2. @dynamic 告訴編譯器耕漱,屬性的setter與getter方法由用戶自己實(shí)現(xiàn)噩斟,不自動生成(如,@dynamic var)孤个。
常見的 Objective-C 的數(shù)據(jù)類型有那些剃允,和C的基本數(shù)據(jù)類型有什么區(qū)別?如:NSInteger和int
答:
Objective-C的數(shù)據(jù)類型有NSString齐鲤,NSNumber斥废,NSArray,NSMutableArray给郊,NSData等等牡肉,這些都是class,創(chuàng)建后便是對象淆九,而C語言的基本數(shù)據(jù)類型int统锤,只是一定字節(jié)的內(nèi)存空間,用于存放數(shù)值;NSInteger是基本數(shù)據(jù)類型炭庙,并不是NSNumber的子類饲窿,當(dāng)然也不是NSObject的子類。NSInteger是基本數(shù)據(jù)類型Int或者Long的別名(NSInteger的定義typedef long NSInteger)焕蹄,它的區(qū)別在于逾雄,NSInteger會根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是long。
id 聲明的對象有什么特性腻脏?
答:id 聲明的對象具有運(yùn)行時(shí)的特性鸦泳,即可以指向任意類型的Objcetive-C的對象。
Objective-C 如何對內(nèi)存管理的永品,說說你的看法和解決方法做鹰?
答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動內(nèi)存計(jì)數(shù))、手動內(nèi)存計(jì)數(shù)鼎姐、內(nèi)存池钾麸。
1). 自動內(nèi)存計(jì)數(shù)ARC:由Xcode自動在App編譯階段掉弛,在代碼中添加內(nèi)存管理代碼。
2). 手動內(nèi)存計(jì)數(shù)MRC:遵循內(nèi)存誰申請喂走、誰釋放;誰添加谋作,誰釋放的原則芋肠。
3). 內(nèi)存釋放池Release Pool:把需要釋放的內(nèi)存統(tǒng)一放在一個池子中,當(dāng)池子被抽干后(drain)遵蚜,池子中所有的內(nèi)存空間也被自動釋放掉帖池。內(nèi)存池的釋放操作分為自動和手動。自動釋放受runloop機(jī)制影響吭净。
Objective-C 中創(chuàng)建線程的方法是什么睡汹?如果在主線程中執(zhí)行代碼,方法是什么寂殉?如果想延時(shí)執(zhí)行代碼囚巴、方法又是什么?
答:線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建友扰、使用GCD的dispatch彤叉、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼,方法是performSelectorOnMainThread村怪,如果想延時(shí)執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:
Category(類別)秽浇、 Extension(擴(kuò)展)和繼承的區(qū)別
區(qū)別:
1. 分類有名字,類擴(kuò)展沒有分類名字甚负,是一種特殊的分類柬焕。
2. 分類只能擴(kuò)展方法(屬性僅僅是聲明,并沒真正實(shí)現(xiàn))梭域,類擴(kuò)展可以擴(kuò)展屬性斑举、成員變量和方法。
3. 繼承可以增加病涨,修改或者刪除方法懂昂,并且可以增加屬性。
我們說的OC是動態(tài)運(yùn)行時(shí)語言是什么意思没宾?
答:主要是將數(shù)據(jù)類型的確定由編譯時(shí)凌彬,推遲到了運(yùn)行時(shí)。簡單來說, 運(yùn)行時(shí)機(jī)制使我們直到運(yùn)行時(shí)才去決定一個對象的類別,以及調(diào)用該類別對象指定方法循衰。
為什么我們常見的delegate屬性都用是week而不是retain/strong铲敛?
答:是為了防止delegate兩端產(chǎn)生不必要的循環(huán)引用。
@property (nonatomic, weak) id delegate;
什么時(shí)候用delete会钝,什么時(shí)候用Notification伐蒋?
Delegate(委托模式):1對1的反向消息通知功能工三。
Notification(通知模式):只想要把消息發(fā)送出去,告知某些狀態(tài)的變化先鱼。但是并不關(guān)心誰想要知道這個俭正。
什么是 KVO 和 KVC?
1). KVC(Key-Value-Coding):鍵值編碼 是一種通過字符串間接訪問對象的方式(即給屬性賦值)
? 舉例說明:
? stu.name = @"張三" // 點(diǎn)語法給屬性賦值
? [stu setValue:@"張三" forKey:@"name"]; // 通過字符串使用KVC方式給屬性賦值
? stu1.nameLabel.text = @"張三";
? [stu1 setValue:@"張三" forKey:@"nameLabel.text"]; // 跨層賦值
2). KVO(key-Value-Observing):鍵值觀察機(jī)制 他提供了觀察某一屬性變化的方法焙畔,極大的簡化了代碼掸读。
? ? KVO只能被KVC觸發(fā),包括使用setValue:forKey:方法和點(diǎn)語法宏多。
? // 通過下方方法為屬性添加KVO觀察
? - (void)addObserver:(NSObject *)observer
? ? ? ? ? ? ? ? ? ? forKeyPath:(NSString *)keyPath
? ? ? ? ? ? ? ? ? ? options:(NSKeyValueObservingOptions)options
? ? ? ? ? ? ? ? ? ? context:(nullable void *)context;
? // 當(dāng)被觀察的屬性發(fā)送變化時(shí)儿惫,會自動觸發(fā)下方方法? ? ? ? ? ? ? ? ?
? - (void)observeValueForKeyPath:(NSString *)keyPath
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ofObject:(id)object
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? change:(NSDictionary *)change
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? context:(void *)context{}
KVC 和 KVO 的 keyPath 可以是屬性、實(shí)例變量伸但、成員變量肾请。
KVC的底層實(shí)現(xiàn)?
當(dāng)一個對象調(diào)用setValue方法時(shí)更胖,方法內(nèi)部會做以下操作:
1). 檢查是否存在相應(yīng)的key的set方法铛铁,如果存在,就調(diào)用set方法却妨。
2). 如果set方法不存在避归,就會查找與key相同名稱并且?guī)聞澗€的成員變量,如果有管呵,則直接給成員變量屬性賦值梳毙。
3). 如果沒有找到_key,就會查找相同名稱的屬性key捐下,如果有就直接賦值摸袁。
4). 如果還沒有找到蹂午,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法侧蘸。
這些方法的默認(rèn)實(shí)現(xiàn)都是拋出異常配名,我們可以根據(jù)需要重寫它們。
KVO的底層實(shí)現(xiàn)婴程?
KVO基于runtime機(jī)制實(shí)現(xiàn)廓奕。
ViewController生命周期
按照執(zhí)行順序排列:
1. initWithCoder:通過nib文件初始化時(shí)觸發(fā)。
2. awakeFromNib:nib文件被加載的時(shí)候档叔,會發(fā)生一個awakeFromNib的消息到nib文件中的每個對象桌粉。? ? ?
3. loadView:開始加載視圖控制器自帶的view。
4. viewDidLoad:視圖控制器的view被加載完成衙四。?
5. viewWillAppear:視圖控制器的view將要顯示在window上铃肯。
6. updateViewConstraints:視圖控制器的view開始更新AutoLayout約束。
7. viewWillLayoutSubviews:視圖控制器的view將要更新內(nèi)容視圖的位置传蹈。
8. viewDidLayoutSubviews:視圖控制器的view已經(jīng)更新視圖的位置押逼。
9. viewDidAppear:視圖控制器的view已經(jīng)展示到window上步藕。
10. viewWillDisappear:視圖控制器的view將要從window上消失。
11. viewDidDisappear:視圖控制器的view已經(jīng)從window上消失挑格。
方法和選擇器有何不同咙冗?
selector是一個方法的名字,方法是一個組合體漂彤,包含了名字和實(shí)現(xiàn)雾消。
你是否接觸過OC中的反射機(jī)制?簡單聊一下概念和使用
1). class反射
通過類名的字符串形式實(shí)例化對象显歧。
Class class = NSClassFromString(@"student");
Student *stu = [[class alloc] init];
將類名變?yōu)樽址?/b>
Class class =[Student class];
NSString *className = NSStringFromClass(class);
2). SEL的反射
通過方法的字符串形式實(shí)例化方法。
SEL selector = NSSelectorFromString(@"setName");?
[stu performSelector:selector withObject:@"Mike"];
將方法變成字符串确镊。
NSStringFromSelector(@selector*(setName:));
調(diào)用方法有兩種方式:
1). 直接通過方法名來調(diào)用士骤。[person show];
2). 間接的通過SEL數(shù)據(jù)來調(diào)用 SEL aaa = @selector(show); [person performSelector:aaa];
如何對iOS設(shè)備進(jìn)行性能測試?
答: Profile-> Instruments ->Time Profiler
開發(fā)項(xiàng)目時(shí)你是怎么檢查內(nèi)存泄露蕾域?
1). 靜態(tài)分析 analyze拷肌。
2). instruments工具里面有個leak可以動態(tài)分析。
什么是懶加載旨巷?
答:懶加載就是只在用到的時(shí)候才去初始化巨缘。也可以理解成延時(shí)加載。
我覺得最好也最簡單的一個例子就是tableView中圖片的加載顯示了, 一個延時(shí)加載, 避免內(nèi)存過高,一個異步加載,避免線程堵塞提高用戶體驗(yàn)采呐。
類變量的 @public若锁,@protected,@private斧吐,@package 聲明各有什么含義又固?
@public 任何地方都能訪問;
@protected 該類和子類中訪問,是默認(rèn)的;
@private 只能在本類中訪問;
@package 本包內(nèi)使用,跨包不可以。
什么是謂詞煤率?
謂詞就是通過NSPredicate給定的邏輯條件作為約束條件,完成對數(shù)據(jù)的篩選仰冠。
//定義謂詞對象,謂詞對象中包含了過濾條件(過濾條件比較多)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<%d",30];
//使用謂詞條件過濾數(shù)組中的元素,過濾之后返回查詢的結(jié)果
NSArray *array = [persons filteredArrayUsingPredicate:predicate];
isa指針問題
isa:是一個Class 類型的指針. 每個實(shí)例對象有個isa的指針,他指向?qū)ο蟮念?而Class里也有個isa的指針, 指向meteClass(元類)。元類保存了類方法的列表蝶糯。當(dāng)類方法被調(diào) 用時(shí),先會從本身查找類方法的實(shí)現(xiàn),如果沒有,元類會向他父類查找該方法洋只。同時(shí)注意的是:元類(meteClass)也是類,它也是對象。元類也有isa指針,它的isa指針最終指向的是一個根元類(root meteClass)昼捍。根元類的isa指針指向本身,這樣形成了一個封閉的內(nèi)循環(huán)识虚。
如何訪問并修改一個類的私有屬性?
1). 一種是通過KVC獲取妒茬。
2). 通過runtime訪問并修改私有屬性舷礼。
一個objc對象的isa的指針指向什么?有什么作用郊闯?
答:指向他的類對象,從而可以找到對象上的方法妻献。
下面的代碼輸出什么蛛株?
@implementation Son : Father
- (id)init {
? if (self = [super init]) {
? ? ? NSLog(@"%@", NSStringFromClass([self class])); // Son
? ? ? NSLog(@"%@", NSStringFromClass([super class])); // Son
? }
? return self;
}
@end
// 解析:
self 是類的隱藏參數(shù),指向當(dāng)前調(diào)用方法的這個類的實(shí)例育拨。
super是一個Magic Keyword谨履,它本質(zhì)是一個編譯器標(biāo)示符,和self是指向的同一個消息接收者熬丧。
不同的是:super會告訴編譯器笋粟,調(diào)用class這個方法時(shí),要去父類的方法析蝴,而不是本類里的害捕。
上面的例子不管調(diào)用[self class]還是[super class],接受消息的對象都是當(dāng)前 Son *obj 這個對象闷畸。
寫一個完整的代理尝盼,包括聲明、實(shí)現(xiàn)
// 創(chuàng)建
@protocol MyDelagate
@required
-(void)eat:(NSString *)foodName;
@optional
-(void)run;
@end
//? 聲明 .h
@interface person: NSObject
@end
//? 實(shí)現(xiàn) .m
@implementation person
- (void)eat:(NSString *)foodName {
? NSLog(@"吃:%@!", foodName);
}
- (void)run {
? NSLog(@"run!");
}
@end
isKindOfClass佑菩、isMemberOfClass盾沫、selector作用分別是什么
isKindOfClass:作用是某個對象屬于某個類型或者繼承自某類型。
isMemberOfClass:某個對象確切屬于某個類型殿漠。
selector:通過方法名赴精,獲取在內(nèi)存中的函數(shù)的入口地址。
delegate 和 notification 的區(qū)別
1). 二者都用于傳遞消息绞幌,不同之處主要在于一個是一對一的蕾哟,另一個是一對多的。
2). notification通過維護(hù)一個array莲蜘,實(shí)現(xiàn)一對多消息的轉(zhuǎn)發(fā)渐苏。
3). delegate需要兩者之間必須建立聯(lián)系,不然沒法調(diào)用代理的方法菇夸;notification不需要兩者之間有聯(lián)系琼富。
什么是block?
閉包(block):閉包就是獲取其它函數(shù)局部變量的匿名函數(shù)庄新。
block反向傳值
在控制器間傳值可以使用代理或者block鞠眉,使用block相對來說簡潔。
在前一個控制器的touchesBegan:方法內(nèi)實(shí)現(xiàn)如下代碼择诈。
? // OneViewController.m
? TwoViewController *twoVC = [[TwoViewController alloc] init];
? twoVC.valueBlcok = ^(NSString *str) {
? NSLog(@"OneViewController拿到值:%@", str);
? };
? [self presentViewController:twoVC animated:YES completion:nil];
? // TwoViewController.h? (在.h文件中聲明一個block屬性)
? @property (nonatomic ,strong) void(^valueBlcok)(NSString *str);
? // TwoViewController.m? (在.m文件中實(shí)現(xiàn)方法)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// 傳值:調(diào)用block
if (_valueBlcok) {
_valueBlcok(@"123456");
}
}
block的注意點(diǎn)
1). 在block內(nèi)部使用外部指針且會造成循環(huán)引用情況下械蹋,需要用__week修飾外部指針:
__weak typeof(self) weakSelf = self;
2). 在block內(nèi)部如果調(diào)用了延時(shí)函數(shù)還使用弱指針會取不到該指針,因?yàn)橐呀?jīng)被銷毀了羞芍,需要在block內(nèi)部再將弱指針重新強(qiáng)引用一下哗戈。
__strong typeof(self) strongSelf = weakSelf;
3). 如果需要在block內(nèi)部改變外部棧區(qū)變量的話,需要在用__block修飾外部變量荷科。
BAD_ACCESS在什么情況下出現(xiàn)唯咬?
答:這種問題在開發(fā)時(shí)經(jīng)常遇到纱注。原因是訪問了野指針,比如訪問已經(jīng)釋放對象的成員變量或者發(fā)消息胆胰、死循環(huán)等狞贱。
lldb(gdb)常用的控制臺調(diào)試命令?
1). p 輸出基本類型蜀涨。是打印命令瞎嬉,需要指定類型。是print的簡寫
p (int)[[[self view] subviews] count]
2). po 打印對象厚柳,會調(diào)用對象description方法氧枣。是print-object的簡寫
po [self view]
3). expr 可以在調(diào)試時(shí)動態(tài)執(zhí)行指定表達(dá)式,并將結(jié)果打印出來别垮。常用于在調(diào)試過程中修改變量的值便监。
4). bt:打印調(diào)用堆棧,是thread backtrace的簡寫宰闰,加all可打印所有thread的堆棧
5). br l:是breakpoint list的簡寫
你一般是怎么用Instruments的茬贵?
Instruments里面工具很多簿透,常用:
1). Time Profiler: 性能分析
2). Zombies:檢查是否訪問了僵尸對象移袍,但是這個工具只能從上往下檢查,不智能老充。
3). Allocations:用來檢查內(nèi)存葡盗,寫算法的那批人也用這個來檢查。
4). Leaks:檢查內(nèi)存啡浊,看是否有內(nèi)存泄露觅够。
iOS中常用的數(shù)據(jù)存儲方式有哪些?
數(shù)據(jù)存儲有四種方案:NSUserDefault巷嚣、KeyChain喘先、file、DB廷粒。
其中File有三種方式:plist窘拯、Archive(歸檔)
DB包括:SQLite、FMDB坝茎、CoreData
iOS的沙盒目錄結(jié)構(gòu)是怎樣的涤姊?
沙盒結(jié)構(gòu):
1). Application:存放程序源文件,上架前經(jīng)過數(shù)字簽名嗤放,上架后不可修改思喊。
2). Documents:常用目錄,iCloud備份目錄次酌,存放數(shù)據(jù)恨课。(這里不能存緩存文件舆乔,否則上架不被通過)
3). Library:
Caches:存放體積大又不需要備份的數(shù)據(jù)。(常用的緩存路徑)
Preference:設(shè)置目錄庄呈,iCloud會備份設(shè)置信息蜕煌。
4). tmp:存放臨時(shí)文件,不會被備份诬留,而且這個文件下的數(shù)據(jù)有可能隨時(shí)被清除的可能斜纪。
iOS多線程技術(shù)有哪幾種方式?
答:pthread文兑、NSThread盒刚、GCD、NSOperation
GCD 與 NSOperation 的區(qū)別:
GCD 和 NSOperation 都是用于實(shí)現(xiàn)多線程:
GCD 基于C語言的底層API绿贞,GCD主要與block結(jié)合使用因块,代碼簡潔高效。
NSOperation 屬于Objective-C類籍铁,是基于GCD更高一層的封裝涡上。復(fù)雜任務(wù)一般用NSOperation實(shí)現(xiàn)。
寫出使用GCD方式從子線程回到主線程的方法代碼
答:dispatch_sync(dispatch_get_main_queue(), ^{ });
如何用GCD同步若干個異步調(diào)用拒名?(如根據(jù)若干個url異步加載多張圖片吩愧,然后在都下載完成后合成一張整圖)
// 使用Dispatch Group追加block到Global Group Queue,這些block如果全部執(zhí)行完畢,就會執(zhí)行Main Dispatch Queue中的結(jié)束處理的block增显。
// 創(chuàng)建隊(duì)列組
dispatch_group_t group = dispatch_group_create();
// 獲取全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{ /*加載圖片1 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片2 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片3 */ });
// 當(dāng)并發(fā)隊(duì)列組中的任務(wù)執(zhí)行完畢后才會執(zhí)行這里的代碼
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
? ? ? ? // 合并圖片
});
dispatch_barrier_async(柵欄函數(shù))的作用是什么雁佳?
函數(shù)定義:dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
作用:
1.在它前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,它后面的任務(wù)要等它執(zhí)行完成后才會開始執(zhí)行同云。
2.避免數(shù)據(jù)競爭
// 1.創(chuàng)建并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
// 2.向隊(duì)列中添加任務(wù)
dispatch_async(queue, ^{? // 1.2是并行的
? ? NSLog(@"任務(wù)1, %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
? ? NSLog(@"任務(wù)2, %@",[NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
? ? NSLog(@"任務(wù) barrier, %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{? // 這兩個是同時(shí)執(zhí)行的
? ? NSLog(@"任務(wù)3, %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
? ? NSLog(@"任務(wù)4, %@",[NSThread currentThread]);
});
// 輸出結(jié)果: 任務(wù)1 任務(wù)2 ——》 任務(wù) barrier ——》任務(wù)3 任務(wù)4
// 其中的任務(wù)1與任務(wù)2糖权,任務(wù)3與任務(wù)4 由于是并行處理先后順序不定冗恨。
以下代碼運(yùn)行結(jié)果如何署穗?
- (void)viewDidLoad {
? ? [super viewDidLoad];
? ? NSLog(@"1");
? ? dispatch_sync(dispatch_get_main_queue(), ^{
? ? ? ? NSLog(@"2");
? ? });
? ? NSLog(@"3");
}
// 只輸出:1泡嘴。(主線程死鎖)
什么是 RunLoop
從字面上講就是運(yùn)行循環(huán)疾瓮,它內(nèi)部就是do-while循環(huán)态兴,在這個循環(huán)內(nèi)部不斷地處理各種任務(wù)岖瑰。
一個線程對應(yīng)一個RunLoop伦意,基本作用就是保持程序的持續(xù)運(yùn)行竖般,處理app中的各種事件咒唆。通過runloop届垫,有事運(yùn)行,沒事就休息全释,可以節(jié)省cpu資源装处,提高程序性能。
主線程的run loop默認(rèn)是啟動的。iOS的應(yīng)用程序里面妄迁,程序啟動后會有一個如下的main()函數(shù)
int main(int argc, char * argv[]) {
@autoreleasepool {
? ? return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
什么是 Runtime
Runtime又叫運(yùn)行時(shí)寝蹈,是一套底層的C語言API,其為iOS內(nèi)部的核心之一登淘,我們平時(shí)編寫的OC代碼箫老,底層都是基于它來實(shí)現(xiàn)的。
Runtime實(shí)現(xiàn)的機(jī)制是什么黔州,怎么用耍鬓,一般用于干嘛?
1). 使用時(shí)需要導(dǎo)入的頭文件
2). Runtime 運(yùn)行時(shí)機(jī)制流妻,它是一套C語言庫牲蜀。
3). 實(shí)際上我們編寫的所有OC代碼,最終都是轉(zhuǎn)成了runtime庫的東西绅这。
比如:
類轉(zhuǎn)成了 Runtime 庫里面的結(jié)構(gòu)體等數(shù)據(jù)類型涣达,
方法轉(zhuǎn)成了 Runtime 庫里面的C語言函數(shù),
平時(shí)調(diào)方法都是轉(zhuǎn)成了 objc_msgSend 函數(shù)(所以說OC有個消息發(fā)送機(jī)制)
// OC是動態(tài)語言证薇,每個方法在運(yùn)行時(shí)會被動態(tài)轉(zhuǎn)為消息發(fā)送度苔,即:objc_msgSend(receiver, selector)。
// [stu show];? 在objc動態(tài)編譯時(shí)浑度,會被轉(zhuǎn)意為:objc_msgSend(stu, @selector(show));
4). 因此寇窑,可以說 Runtime 是OC的底層實(shí)現(xiàn),是OC的幕后執(zhí)行者俺泣。
有了Runtime庫疗认,能做什么事情呢完残?
Runtime庫里面包含了跟類伏钠、成員變量、方法相關(guān)的API谨设。
比如:
? ? (1)獲取類里面的所有成員變量熟掂。
? ? (2)為類動態(tài)添加成員變量。
? ? (3)動態(tài)改變類的方法實(shí)現(xiàn)扎拣。
? ? (4)為類動態(tài)添加新的方法等赴肚。
因此,有了Runtime二蓝,想怎么改就怎么改誉券。
什么是 Method Swizzle(黑魔法),什么情況下會使用刊愚?
1). 在沒有一個類的實(shí)現(xiàn)源碼的情況下踊跟,想改變其中一個方法的實(shí)現(xiàn),除了繼承它重寫鸥诽、和借助類別重名方法暴力搶先之外商玫,還有更加靈活的方法 Method Swizzle箕憾。
2). Method Swizzle 指的是改變一個已存在的選擇器對應(yīng)的實(shí)現(xiàn)的過程。OC中方法的調(diào)用能夠在運(yùn)行時(shí)通過改變拳昌,通過改變類的調(diào)度表中選擇器到最終函數(shù)間的映射關(guān)系袭异。
3). 在OC中調(diào)用一個方法,其實(shí)是向一個對象發(fā)送消息炬藤,查找消息的唯一依據(jù)是selector的名字御铃。利用OC的動態(tài)特性,可以實(shí)現(xiàn)在運(yùn)行時(shí)偷換selector對應(yīng)的方法實(shí)現(xiàn)沈矿。
4). 每個類都有一個方法列表畅买,存放著selector的名字和方法實(shí)現(xiàn)的映射關(guān)系。IMP有點(diǎn)類似函數(shù)指針细睡,指向具體的方法實(shí)現(xiàn)谷羞。
5). 我們可以利用 method_exchangeImplementations 來交換2個方法中的IMP。
6). 我們可以利用 class_replaceMethod 來修改類溜徙。
7). 我們可以利用 method_setImplementation 來直接設(shè)置某個方法的IMP湃缎。
8). 歸根結(jié)底,都是偷換了selector的IMP蠢壹。
_objc_msgForward 函數(shù)是做什么的嗓违,直接調(diào)用它將會發(fā)生什么?
答:_objc_msgForward是 IMP 類型图贸,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個對象發(fā)送一條消息蹂季,但它并沒有實(shí)現(xiàn)的時(shí)候,_objc_msgForward會嘗試做消息轉(zhuǎn)發(fā)疏日。
什么是 TCP / UDP ?
TCP:傳輸控制協(xié)議偿洁。
UDP:用戶數(shù)據(jù)協(xié)議。
TCP 是面向連接的沟优,建立連接需要經(jīng)歷三次握手涕滋,是可靠的傳輸層協(xié)議。
UDP 是面向無連接的挠阁,數(shù)據(jù)傳輸是不可靠的宾肺,它只管發(fā),不管收不收得到侵俗。
簡單的說锨用,TCP注重?cái)?shù)據(jù)安全,而UDP數(shù)據(jù)傳輸快點(diǎn)隘谣,但安全性一般增拥。
通信底層原理(OSI七層模型)
OSI采用了分層的結(jié)構(gòu)化技術(shù),共分七層:
物理層、數(shù)據(jù)鏈路層跪者、網(wǎng)絡(luò)層棵帽、傳輸層、會話層渣玲、表示層逗概、應(yīng)用層。
介紹一下XMPP忘衍?
XMPP是一種以XML為基礎(chǔ)的開放式實(shí)時(shí)通信協(xié)議逾苫。
簡單的說,XMPP就是一種協(xié)議枚钓,一種規(guī)定铅搓。就是說,在網(wǎng)絡(luò)上傳東西搀捷,XMM就是規(guī)定你上傳大小的格式星掰。
OC中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼嫩舟,方法是什么氢烘?
// 創(chuàng)建線程的方法
- [NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil]
- [self performSelectorInBackground:nil withObject:nil];
- [[NSThread alloc] initWithTarget:nil selector:nil object:nil];
- dispatch_async(dispatch_get_global_queue(0, 0), ^{});
- [[NSOperationQueue new] addOperation:nil];
// 主線程中執(zhí)行代碼的方法
- [self performSelectorOnMainThread:nil withObject:nil waitUntilDone:YES];
- dispatch_async(dispatch_get_main_queue(), ^{});
- [[NSOperationQueue mainQueue] addOperation:nil];
tableView的重用機(jī)制?
答:UITableView 通過重用單元格來達(dá)到節(jié)省內(nèi)存的目的: 通過為每個單元格指定一個重用標(biāo)識符家厌,即指定了單元格的種類,當(dāng)屏幕上的單元格滑出屏幕時(shí)播玖,系統(tǒng)會把這個單元格添加到重用隊(duì)列中,等待被重用饭于,當(dāng)有新單元格從屏幕外滑入屏幕內(nèi)時(shí)蜀踏,從重用隊(duì)列中找看有沒有可以重用的單元格,如果有掰吕,就拿過來用果覆,如果沒有就創(chuàng)建一個來使用。
用偽代碼寫一個線程安全的單例模式
static id _instance;
+ (id)allocWithZone:(struct _NSZone *)zone {
? static dispatch_once_t onceToken;
? dispatch_once(&onceToken, ^{
? ? ? _instance = [super allocWithZone:zone];
? });
? return _instance;
}
+ (instancetype)sharedData {
? static dispatch_once_t onceToken;
? dispatch_once(&onceToken, ^{
? ? ? _instance = [[self alloc] init];
? });
? return _instance;
}
- (id)copyWithZone:(NSZone *)zone {
? return _instance;
}
如何實(shí)現(xiàn)視圖的變形?
答:通過修改view的 transform 屬性即可畴栖。
在手勢對象基礎(chǔ)類UIGestureRecognizer的常用子類手勢類型中哪兩個手勢發(fā)生后随静,響應(yīng)只會執(zhí)行一次八千?
答:UITapGestureRecognizer,UISwipeGestureRecognizer是一次性手勢,手勢發(fā)生后,響應(yīng)只會執(zhí)行一次吗讶。
字符串常用方法:
NSString *str = @"abc*123";
NSArray *arr = [str componentsSeparatedByString:@"*"]; //以目標(biāo)字符串把原字符串分割成兩部分,存到數(shù)組中恋捆。@[@"abc", @"123"];
如何高性能的給 UIImageView 加個圓角?
不好的解決方案:使用下面的方式會強(qiáng)制Core Animation提前渲染屏幕的離屏繪制, 而離屏繪制就會給性能帶來負(fù)面影響照皆,會有卡頓的現(xiàn)象出現(xiàn)。
self.view.layer.cornerRadius = 5.0f;
self.view.layer.masksToBounds = YES;
正確的解決方案:使用繪圖技術(shù)
- (UIImage *)circleImage {
? ? // NO代表透明
? ? UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
? ? // 獲得上下文
? ? CGContextRef ctx = UIGraphicsGetCurrentContext();
? ? // 添加一個圓
? ? CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
? ? CGContextAddEllipseInRect(ctx, rect);
? ? // 裁剪
? ? CGContextClip(ctx);
? ? // 將圖片畫上去
? ? [self drawInRect:rect];
? ? UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
? ? // 關(guān)閉上下文
? ? UIGraphicsEndImageContext();
? ? return image;
}
還有一種方案:使用了貝塞爾曲線"切割"個這個圖片, 給UIImageView 添加了的圓角沸停,其實(shí)也是通過繪圖技術(shù)來實(shí)現(xiàn)的膜毁。
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.center = CGPointMake(200, 300);
UIImage *anotherImage = [UIImage imageNamed:@"image"];
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
? ? ? ? ? ? ? ? ? ? ? cornerRadius:50] addClip];
[anotherImage drawInRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.view addSubview:imageView];
你是怎么封裝一個view的
1). 可以通過純代碼或者xib的方式來封裝子控件2). 建立一個跟view相關(guān)的模型,然后將模型數(shù)據(jù)傳給view,通過模型上的數(shù)據(jù)給view的子控件賦值/** *? 純代碼初始化控件時(shí)一定會走這個方法 */- (instancetype)initWithFrame:(CGRect)frame {? ? if(self = [super initWithFrame:frame]) {? ? ? ? [self setupUI];? ? }
? ? return self;
}
/**
*? 通過xib初始化控件時(shí)一定會走這個方法
*/
- (id)initWithCoder:(NSCoder *)aDecoder {
? ? if(self = [super initWithCoder:aDecoder]) {
? ? ? ? [self setupUI];
? ? }
? ? return self;
}
- (void)setupUI {
? ? // 初始化代碼
}
HTTP協(xié)議中 POST 方法和 GET 方法有那些區(qū)別?
1. GET用于向服務(wù)器請求數(shù)據(jù)瘟滨,POST用于提交數(shù)據(jù)
2. GET請求候醒,請求參數(shù)拼接形式暴露在地址欄,而POST請求參數(shù)則放在請求體里面杂瘸,因此GET請求不適合用于驗(yàn)證密碼等操作
3. GET請求的URL有長度限制倒淫,POST請求不會有長度限制
請簡單的介紹下APNS發(fā)送系統(tǒng)消息的機(jī)制
APNS優(yōu)勢:杜絕了類似安卓那種為了接受通知不停在后臺喚醒程序保持長連接的行為,由iOS系統(tǒng)和APNS進(jìn)行長連接替代败玉。
APNS的原理:
1). 應(yīng)用在通知中心注冊敌土,由iOS系統(tǒng)向APNS請求返回設(shè)備令牌(device Token)
2). 應(yīng)用程序接收到設(shè)備令牌并發(fā)送給自己的后臺服務(wù)器
3). 服務(wù)器把要推送的內(nèi)容和設(shè)備發(fā)送給APNS
4). APNS根據(jù)設(shè)備令牌找到設(shè)備,再由iOS根據(jù)APPID把推送內(nèi)容展示
?
AFNetworking 底層原理分析
AFNetworking主要是對NSURLSession和NSURLConnection(iOS9.0廢棄)的封裝,其中主要有以下類:
1). AFHTTPRequestOperationManager:內(nèi)部封裝的是 NSURLConnection, 負(fù)責(zé)發(fā)送網(wǎng)絡(luò)請求, 使用最多的一個類运翼。(3.0廢棄)
2). AFHTTPSessionManager:內(nèi)部封裝是 NSURLSession, 負(fù)責(zé)發(fā)送網(wǎng)絡(luò)請求,使用最多的一個類返干。
3). AFNetworkReachabilityManager:實(shí)時(shí)監(jiān)測網(wǎng)絡(luò)狀態(tài)的工具類。當(dāng)前的網(wǎng)絡(luò)環(huán)境發(fā)生改變之后,這個工具類就可以檢測到血淌。
4). AFSecurityPolicy:網(wǎng)絡(luò)安全的工具類, 主要是針對 HTTPS 服務(wù)矩欠。
5). AFURLRequestSerialization:序列化工具類,基類。上傳的數(shù)據(jù)轉(zhuǎn)換成JSON格式
(AFJSONRequestSerializer).使用不多悠夯。
6). AFURLResponseSerialization:反序列化工具類;基類.使用比較多:
7). AFJSONResponseSerializer; JSON解析器,默認(rèn)的解析器.
8). AFHTTPResponseSerializer; 萬能解析器; JSON和XML之外的數(shù)據(jù)類型,直接返回二進(jìn)
制數(shù)據(jù).對服務(wù)器返回的數(shù)據(jù)不做任何處理.
9). AFXMLParserResponseSerializer; XML解析器;
描述下SDWebImage里面給UIImageView加載圖片的邏輯
SDWebImage 中為 UIImageView 提供了一個分類UIImageView+WebCache.h, 這個分類中有一個最常用的接口sd_setImageWithURL:placeholderImage:晚顷,會在真實(shí)圖片出現(xiàn)前會先顯示占位圖片,當(dāng)真實(shí)圖片被加載出來后再替換占位圖片疗疟。
加載圖片的過程大致如下:
1.首先會在 SDWebImageCache 中尋找圖片是否有對應(yīng)的緩存, 它會以url 作為數(shù)據(jù)的索引先在內(nèi)存中尋找是否有對應(yīng)的緩存
2.如果緩存未找到就會利用通過MD5處理過的key來繼續(xù)在磁盤中查詢對應(yīng)的數(shù)據(jù), 如果找到了, 就會把磁盤中的數(shù)據(jù)加載到內(nèi)存中该默,并將圖片顯示出來
3.如果在內(nèi)存和磁盤緩存中都沒有找到,就會向遠(yuǎn)程服務(wù)器發(fā)送請求策彤,開始下載圖片
4.下載后的圖片會加入緩存中栓袖,并寫入磁盤中
5.整個獲取圖片的過程都是在子線程中執(zhí)行,獲取到圖片后回到主線程將圖片顯示出來
SDWebImage原理:
調(diào)用類別的方法:
1. 從內(nèi)存(字典)中找圖片(當(dāng)這個圖片在本次使用程序的過程中已經(jīng)被加載過)店诗,找到直接使用裹刮。
2. 從沙盒中找(當(dāng)這個圖片在之前使用程序的過程中被加載過),找到使用庞瘸,緩存到內(nèi)存中捧弃。
3. 從網(wǎng)絡(luò)上獲取,使用擦囊,緩存到內(nèi)存违霞,緩存到沙盒。
友盟統(tǒng)計(jì)接口統(tǒng)計(jì)的所有功能
APP啟動速度瞬场,APP停留頁面時(shí)間等
不用中間變量,用兩種方法交換A和B的值
// 1.中間變量
void swap(int a, int b) {
? int temp = a;
? a = b;
? b = temp;
}
// 2.加法
void swap(int a, int b) {
? a = a + b;
? b = a - b;
? a = a - b;
}
// 3.異或(相同為0买鸽,不同為1. 可以理解為不進(jìn)位加法)
void swap(int a, int b) {
? a = a ^ b;
? b = a ^ b;
? a = a ^ b;
}
?
求最大公約數(shù)
/** 1.直接遍歷法 */
int maxCommonDivisor(int a, int b) {
? ? int max = 0;
? ? for (int i = 1; i <=b; i++) {
? ? ? ? if (a % i == 0 && b % i == 0) {
? ? ? ? ? ? max = i;
? ? ? ? }
? ? }
? ? return max;
}
/** 2.輾轉(zhuǎn)相除法 */
int maxCommonDivisor(int a, int b) {
? ? int r;
? ? while(a % b > 0) {
? ? ? ? r = a % b;
? ? ? ? a = b;
? ? ? ? b = r;
? ? }
? ? return b;
}
// 擴(kuò)展:最小公倍數(shù) = (a * b)/最大公約數(shù)
模擬棧操作
/**
?*? 棧是一種數(shù)據(jù)結(jié)構(gòu)备畦,特點(diǎn):先進(jìn)后出
?*? 練習(xí):使用全局變量模擬棧的操作
?*/
#include
#include
#include
//保護(hù)全局變量:在全局變量前加static后洁桌,這個全局變量就只能在本文件中使用
static int data[1024];//棧最多能保存1024個數(shù)據(jù)
static int count = 0;//目前已經(jīng)放了多少個數(shù)(相當(dāng)于棧頂位置)
//數(shù)據(jù)入棧 push
void push(int x){
? assert(!full());//防止數(shù)組越界
data[count++] = x;
}
//數(shù)據(jù)出棧 pop
int pop(){
assert(!empty());
return data[--count];
}
//查看棧頂元素 top
int top(){
assert(!empty());
return data[count-1];
}
//查詢棧滿 full
bool full() {
if(count >= 1024) {
? ? return 1;
}
? ? return 0;
}
//查詢棧空 empty
bool empty() {
if(count <= 0) {
return 1;
}
? ? return 0;
}
int main(){
? ? //入棧
? ? for (int i = 1; i <= 10; i++) {
? ? ? ? push(i);
? ? }
? ? //出棧
? ? while(!empty()){
? ? ? ? printf("%d ", top()); //棧頂元素
? ? ? ? pop(); //出棧
? ? }
? ? printf("\n");
? ? return 0;
}
排序算法
選擇排序植康、冒泡排序、插入排序三種排序算法可以總結(jié)為如下:
都將數(shù)組分為已排序部分和未排序部分看幼。
1. 選擇排序?qū)⒁雅判虿糠侄x在左端批旺,然后選擇未排序部分的最小元素和未排序部分的第一個元素交換。
2. 冒泡排序?qū)⒁雅判虿糠侄x在右端诵姜,在遍歷未排序部分的過程執(zhí)行交換朱沃,將最大元素交換到最右端。
3. 插入排序?qū)⒁雅判虿糠侄x在左端茅诱,將未排序部分元的第一個元素插入到已排序部分合適的位置逗物。
選擇排序
/**
* 【選擇排序】:最值出現(xiàn)在起始端
*
* 第1趟:在n個數(shù)中找到最小(大)數(shù)與第一個數(shù)交換位置
* 第2趟:在剩下n-1個數(shù)中找到最小(大)數(shù)與第二個數(shù)交換位置
* 重復(fù)這樣的操作...依次與第三個、第四個...數(shù)交換位置
* 第n-1趟瑟俭,最終可實(shí)現(xiàn)數(shù)據(jù)的升序(降序)排列翎卓。
*
*/
void selectSort(int *arr, int length) {
? ? for (int i = 0; i < length - 1; i++) { //趟數(shù)
? ? ? ? for (int j = i + 1; j < length; j++) { //比較次數(shù)
? ? ? ? ? ? if (arr[i] > arr[j]) {
? ? ? ? ? ? ? ? int temp = arr[i];
? ? ? ? ? ? ? ? arr[i] = arr[j];
? ? ? ? ? ? ? ? arr[j] = temp;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
冒泡排序
/**
* 【冒泡排序】:相鄰元素兩兩比較,比較完一趟摆寄,最值出現(xiàn)在末尾
* 第1趟:依次比較相鄰的兩個數(shù)失暴,不斷交換(小數(shù)放前,大數(shù)放后)逐個推進(jìn)微饥,最值最后出現(xiàn)在第n個元素位置
* 第2趟:依次比較相鄰的兩個數(shù)逗扒,不斷交換(小數(shù)放前,大數(shù)放后)逐個推進(jìn)欠橘,最值最后出現(xiàn)在第n-1個元素位置
* ……? ……
* 第n-1趟:依次比較相鄰的兩個數(shù)矩肩,不斷交換(小數(shù)放前,大數(shù)放后)逐個推進(jìn)肃续,最值最后出現(xiàn)在第2個元素位置
*/
void bublleSort(int *arr, int length) {
? ? for(int i = 0; i < length - 1; i++) { //趟數(shù)
? ? ? ? for(int j = 0; j < length - i - 1; j++) { //比較次數(shù)
? ? ? ? ? ? if(arr[j] > arr[j+1]) {
? ? ? ? ? ? ? ? int temp = arr[j];
? ? ? ? ? ? ? ? arr[j] = arr[j+1];
? ? ? ? ? ? ? ? arr[j+1] = temp;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
折半查找(二分查找)
/**
* 折半查找:優(yōu)化查找時(shí)間(不用遍歷全部數(shù)據(jù))
*
* 折半查找的原理:
*? 1> 數(shù)組必須是有序的
*? 2> 必須已知min和max(知道范圍)
*? 3> 動態(tài)計(jì)算mid的值黍檩,取出mid對應(yīng)的值進(jìn)行比較
*? 4> 如果mid對應(yīng)的值大于要查找的值,那么max要變小為mid-1
*? 5> 如果mid對應(yīng)的值小于要查找的值始锚,那么min要變大為mid+1
*
*/
// 已知一個有序數(shù)組, 和一個key, 要求從數(shù)組中找到key對應(yīng)的索引位置
int findKey(int *arr, int length, int key) {
? ? int min = 0, max = length - 1, mid;
? ? while (min <= max) {
? ? ? ? mid = (min + max) / 2; //計(jì)算中間值
? ? ? ? if (key > arr[mid]) {
? ? ? ? ? ? min = mid + 1;
? ? ? ? } else if (key < arr[mid]) {
? ? ? ? ? ? max = mid - 1;
? ? ? ? } else {
? ? ? ? ? ? return mid;
? ? ? ? }
? ? }
? ? return -1;
}
?
編碼格式(優(yōu)化細(xì)節(jié))
在 Objective-C 中刽酱,enum 建議使用?NS_ENUM?和?NS_OPTIONS?宏來定義枚舉類型。
//定義一個枚舉(比較嚴(yán)密)
typedef NS_ENUM(NSInteger, BRUserGender) {
? ? BRUserGenderUnknown, // 未知
? ? BRUserGenderMale, // 男性
? ? BRUserGenderFemale, // 女性
? ? BRUserGenderNeuter // 無性
};
@interface BRUser : NSObject
@property (nonatomic, readonly, copy) NSString *name;
@property (nonatomic, readonly, assign) NSUInteger age;
@property (nonatomic, readonly, assign) BRUserGender gender;
- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age gender:(BRUserGender)gender;
@end
//說明:
//既然該類中已經(jīng)有一個“初始化方法” 瞧捌,用于設(shè)置 name棵里、age 和 gender 的初始值: 那么在設(shè)計(jì)對應(yīng) @property 時(shí)就應(yīng)該盡量使用不可變的對象:其三個屬性都應(yīng)該設(shè)為“只讀”。用初始化方法設(shè)置好屬性值之后姐呐,就不能再改變了殿怜。
//屬性的參數(shù)應(yīng)該按照下面的順序排列: (原子性,讀寫皮钠,內(nèi)存管理)
?
避免使用C語言中的基本數(shù)據(jù)類型稳捆,建議使用 Foundation 數(shù)據(jù)類型,對應(yīng)關(guān)系如下:
int -> NSInteger
unsigned -> NSUInteger
float -> CGFloat
動畫時(shí)間 -> NSTimeInterval
?
HomeKit麦轰,是蘋果2014年發(fā)布的智能家居平臺乔夯。
什么是 OpenGL、Quartz 2D款侵?
Quatarz?2d?是Apple提供的基本圖形工具庫末荐。只是適用于2D圖形的繪制。
OpenGL新锈,是一個跨平臺的圖形開發(fā)庫甲脏。適用于2D和3D圖形的繪制。
ffmpeg框架:?ffmpeg 是音視頻處理工具妹笆,既有音視頻編碼解碼功能块请,又可以作為播放器使用。
談?wù)?UITableView 的優(yōu)化
1). 正確的復(fù)用cell拳缠。
2). 設(shè)計(jì)統(tǒng)一規(guī)格的Cell
3). 提前計(jì)算并緩存好高度(布局)墩新,因?yàn)閔eightForRowAtIndexPath:是調(diào)用最頻繁的方法;
4). 異步繪制窟坐,遇到復(fù)雜界面海渊,遇到性能瓶頸時(shí),可能就是突破口哲鸳;
4). 滑動時(shí)按需加載臣疑,這個在大量圖片展示,網(wǎng)絡(luò)加載的時(shí)候很管用徙菠!
5). 減少子視圖的層級關(guān)系
6). 盡量使所有的視圖不透明化以及做切圓操作讯沈。
7). 不要動態(tài)的add 或者 remove 子控件。最好在初始化時(shí)就添加完婿奔,然后通過hidden來控制是否顯示芙盘。
8). 使用調(diào)試工具分析問題。
如何實(shí)行cell的動態(tài)的行高
如果希望每條數(shù)據(jù)顯示自身的行高脸秽,必須設(shè)置兩個屬性儒老,1.預(yù)估行高,2.自定義行高记餐。
設(shè)置預(yù)估行高 tableView.estimatedRowHeight = 200驮樊。
設(shè)置定義行高 tableView.estimatedRowHeight = UITableViewAutomaticDimension。
如果要讓自定義行高有效片酝,必須讓容器視圖有一個自下而上的約束囚衔。
說說你對 block 的理解
棧上的自動復(fù)制到堆上,block 的屬性修飾符是 copy雕沿,循環(huán)引用的原理和解決方案练湿。
說說你對 runtime 的理解
主要是方法調(diào)用時(shí)如何查找緩存,如何找到方法审轮,找不到方法時(shí)怎么轉(zhuǎn)發(fā)肥哎,對象的內(nèi)存布局辽俗。
什么是野指針、空指針篡诽?
野指針:不知道指向了哪里的指針叫野指針崖飘。即指針指向不確定,指針存的地址是一個垃圾值杈女,未初始化朱浴。
空指針:不指向任何位置的指針叫空指針。即指針沒有指向达椰,指針存的地址是一個空地址翰蠢,NULL。
什么是 OOA / OOD / OOP ?
OOA(Object Oriented Analysis) ? --面向?qū)ο蠓治?/b>
OOD(Object Oriented Design) ? ? --面向?qū)ο笤O(shè)計(jì)
OOP(Object Oriented Programming)--面向?qū)ο缶幊?/b>
1. Object-c的類可以多重繼承么?可以實(shí)現(xiàn)多個接口么?Category是什么?重寫一個類的方式用繼承好還是分類好?為什么?
答: Object-c的類不可以多重繼承;可以實(shí)現(xiàn)多個接口啰劲,通過實(shí)現(xiàn)多個接口可以完成C++的多重繼承;Category是類別梁沧,一般情況用分類好,用Category去重寫類的方法呈枉,僅對本Category有效趁尼,不會影響到其他類與原有類的關(guān)系。
2. #import 跟#include 又什么區(qū)別猖辫,@class呢, #import<> 跟 #import””又什么區(qū)別?
答:#import是Objective-C導(dǎo)入頭文件的關(guān)鍵字酥泞,#include是C/C++導(dǎo)入頭文件的關(guān)鍵字,使用#import頭文件會自動只導(dǎo)入一次,不會重復(fù)導(dǎo)入啃憎,相當(dāng)于#include和#pragma once;@class告訴編譯器某個類的聲明芝囤,當(dāng)執(zhí)行時(shí),才去查看類的實(shí)現(xiàn)文件辛萍,可以解決頭文件的相互包含;#import<>用來包含系統(tǒng)的頭文件悯姊,#import””用來包含用戶頭文件。
3. 屬性readwrite贩毕,readonly悯许,assign,retain辉阶,copy先壕,nonatomic 各是什么作用,在那種情況下用?
答:
1). readwrite 是可讀可寫特性;需要生成getter方法和setter方法時(shí)
2). readonly 是只讀特性 只會生成getter方法 不會生成setter方法 ;不希望屬性在類外改變
3). assign 是賦值特性谆甜,setter方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí);
4). retain 表示持有特性垃僚,setter方法將傳入?yún)?shù)先保留,再賦值规辱,傳入?yún)?shù)的retaincount會+1;
5). copy 表示賦值特性谆棺,setter方法將傳入對象復(fù)制一份;需要完全一份新的變量時(shí)。
6).nonatomic 非原子操作罕袋,決定編譯器生成的setter getter是否是原子操作改淑,atomic表示多線程安全碍岔,一般使用nonatomic **
4.寫一個setter方法用于完成@property (nonatomic,retain)NSString name,寫一個setter方法用于完成@property(nonatomic,copy)NSString name
答:
5.對于語句NSStringobj = [[NSData alloc] init]; obj在編譯時(shí)和運(yùn)行時(shí)分別時(shí)什么類型的對象?
* 答: 編譯時(shí)是NSString的類型;運(yùn)行時(shí)是NSData類型的對象
6.常見的object-c的數(shù)據(jù)類型有那些溅固, 和C的基本數(shù)據(jù)類型有什么區(qū)別?如:NSInteger和int
答:object-c的數(shù)據(jù)類型有NSString付秕,NSNumber兰珍,NSArray侍郭,NSMutableArray,NSData等等掠河,這些都是class亮元,創(chuàng)建后便是對象,而C語言的基本數(shù)據(jù)類型int唠摹,只是一定字節(jié)的內(nèi)存空間爆捞,用于存放數(shù)值;NSInteger是基本數(shù)據(jù)類型,并不是NSNumber的子類勾拉,當(dāng)然也不是NSObject的子類煮甥。NSInteger是基本數(shù)據(jù)類型Int或者Long的別名(NSInteger的定義typedef long NSInteger),它的區(qū)別在于藕赞,NSInteger會根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是Long成肘。
7.id 聲明的對象有什么特性?
答:Id 聲明的對象具有運(yùn)行時(shí)的特性,即可以指向任意類型的objcetive-c的對象;
8.Objective-C如何對內(nèi)存管理的,說說你的看法和解決方法?
答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動內(nèi)存計(jì)數(shù))斧蜕、手動內(nèi)存計(jì)數(shù)双霍、內(nèi)存池。
1). (Garbage Collection)自動內(nèi)存計(jì)數(shù):這種方式和java類似批销,在你的程序的執(zhí)行過程中洒闸。始終有一個高人在背后準(zhǔn)確地幫你收拾垃圾,你不用考慮它什么時(shí)候開始工作均芽,怎樣工作丘逸。你只需要明白,我申請了一段內(nèi)存空間掀宋,當(dāng)我不再使用從而這段內(nèi)存成為垃圾的時(shí)候深纲,我就徹底的把它忘記掉,反正那個高人會幫我收拾垃圾布朦。遺憾的是囤萤,那個高人需要消耗一定的資源,在攜帶設(shè)備里面是趴,資源是緊俏商品所以iPhone不支持這個功能涛舍。所以“Garbage Collection”不是本入門指南的范圍,對“Garbage Collection”內(nèi)部機(jī)制感興趣的同學(xué)可以參考一些其他的資料唆途,不過說老實(shí)話“Garbage Collection”不大適合適初學(xué)者研究富雅。 解決: 通過alloc – initial方式創(chuàng)建的, 創(chuàng)建后引用計(jì)數(shù)+1, 此后每retain一次引用計(jì)數(shù)+1, 那么在程序中做相應(yīng)次數(shù)的release就好了.
2). (Reference Counted)手動內(nèi)存計(jì)數(shù):就是說掸驱,從一段內(nèi)存被申請之后,就存在一個變量用于保存這段內(nèi)存被使用的次數(shù)没佑,我們暫時(shí)把它稱為計(jì)數(shù)器毕贼,當(dāng)計(jì)數(shù)器變?yōu)?的時(shí)候,那么就是釋放這段內(nèi)存的時(shí)候蛤奢。比如說鬼癣,當(dāng)在程序A里面一段內(nèi)存被成功申請完成之后,那么這個計(jì)數(shù)器就從0變成1(我們把這個過程叫做alloc)啤贩,然后程序B也需要使用這個內(nèi)存待秃,那么計(jì)數(shù)器就從1變成了2(我們把這個過程叫做retain)。緊接著程序A不再需要這段內(nèi)存了痹屹,那么程序A就把這個計(jì)數(shù)器減1(我們把這個過程叫做release);程序B也不再需要這段內(nèi)存的時(shí)候章郁,那么也把計(jì)數(shù)器減1(這個過程還是release)。當(dāng)系統(tǒng)(也就是Foundation)發(fā)現(xiàn)這個計(jì)數(shù)器變 成員了0志衍,那么就會調(diào)用內(nèi)存回收程序把這段內(nèi)存回收(我們把這個過程叫做dealloc)暖庄。順便提一句,如果沒有Foundation楼肪,那么維護(hù)計(jì)數(shù)器培廓,釋放內(nèi)存等等工作需要你手工來完成。 解決:一般是由類的靜態(tài)方法創(chuàng)建的, 函數(shù)名中不會出現(xiàn)alloc或init字樣, 如[NSString string]和[NSArray arrayWithObject:], 創(chuàng)建后引用計(jì)數(shù)+0, 在函數(shù)出棧后釋放, 即相當(dāng)于一個棧上的局部變量. 當(dāng)然也可以通過retain延長對象的生存期.
3). (NSAutoRealeasePool)內(nèi)存池:可以通過創(chuàng)建和釋放內(nèi)存池控制內(nèi)存申請和回收的時(shí)機(jī). 解決:是由autorelease加入系統(tǒng)內(nèi)存池, 內(nèi)存池是可以嵌套的, 每個內(nèi)存池都需要有一個創(chuàng)建釋放對, 就像main函數(shù)中寫的一樣. 使用也很簡單, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即將一個NSString對象加入到最內(nèi)層的系統(tǒng)內(nèi)存池, 當(dāng)我們釋放這個內(nèi)存池時(shí), 其中的對象都會被釋放.
9. 原子(atomic)跟非原子(non-atomic)屬性有什么區(qū)別?
答:
1). atomic提供多線程安全淹辞。是防止在寫未完成的時(shí)候被另外一個線程讀取医舆,造成數(shù)據(jù)錯誤
2). non-atomic:在自己管理內(nèi)存的環(huán)境中业扒,解析的訪問器保留并自動釋放返回的值皿曲,如果指定了 nonatomic ,那么訪問器只是簡單地返回這個值渡八。
10. 看下面的程序,第一個NSLog會輸出什么?這時(shí)str的retainCount是多少?第二個和第三個呢? 為什么?
str的retainCount創(chuàng)建+1央星,retain+1霞怀,加入數(shù)組自動+1 3 retain+1,release-1莉给,release-1 2 數(shù)組刪除所有對象毙石,所有數(shù)組內(nèi)的對象自動-1 1
11. 內(nèi)存管理的幾條原則時(shí)什么?按照默認(rèn)法則.那些關(guān)鍵字生成的對象需要手動釋放?在和property結(jié)合的時(shí)候怎樣有效的避免內(nèi)存泄露?
答:誰申請,誰釋放 遵循Cocoa Touch的使用原則; 內(nèi)存管理主要要避免“過早釋放”和“內(nèi)存泄漏”颓遏,對于“過早釋放”需要注意@property設(shè)置特性時(shí)徐矩,一定要用對特性關(guān)鍵字,對于“內(nèi)存泄漏”叁幢,一定要申請了要負(fù)責(zé)釋放滤灯,要細(xì)心。 關(guān)鍵字alloc 或new 生成的對象需要手動釋放; 設(shè)置正確的property屬性,對于retain需要在合適的地方釋放鳞骤,
12.如何對iOS設(shè)備進(jìn)行性能測試?
答: Profile-> Instruments ->Time Profiler
13. Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼窒百,方法是什么?如果想延時(shí)執(zhí)行代碼、方法又是什么?
答:線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建豫尽、使用GCD的dispatch篙梢、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼,方法是performSelectorOnMainThread美旧,如果想延時(shí)執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:
14. MVC設(shè)計(jì)模式是什么渤滞? 你還熟悉什么設(shè)計(jì)模式?
答: 設(shè)計(jì)模式:并不是一種新技術(shù)陈症,而是一種編碼經(jīng)驗(yàn)蔼水,使用比如java中的接口震糖,iphone中的協(xié)議录肯,繼承關(guān)系等基本手段,用比較成熟的邏輯去處理某一種類型的事情吊说,總結(jié)為所謂設(shè)計(jì)模式论咏。面向?qū)ο缶幊讨校琷ava已經(jīng)歸納了23種設(shè)計(jì)模式颁井。
mvc設(shè)計(jì)模式 :模型厅贪,視圖,控制器雅宾,可以將整個應(yīng)用程序在思想上分成三大塊养涮,對應(yīng)是的數(shù)據(jù)的存儲或處理,前臺的顯示眉抬,業(yè)務(wù)邏輯的控制贯吓。 Iphone本身的設(shè)計(jì)思想就是遵循mvc設(shè)計(jì)模式。其不屬于23種設(shè)計(jì)模式范疇蜀变。
代理模式:代理模式給某一個對象提供一個代理對象悄谐,并由代理對象控制對源對象的引用.比如一個工廠生產(chǎn)了產(chǎn)品,并不想直接賣給用戶库北,而是搞了很多代理商爬舰,用戶可以直接找代理商買東西,代理商從工廠進(jìn)貨.常見的如QQ的自動回復(fù)就屬于代理攔截寒瓦,代理模式在iphone中得到廣泛應(yīng)用. 單例模式:說白了就是一個類不通過alloc方式創(chuàng)建對象情屹,而是用一個靜態(tài)方法返回這個類的對象。系統(tǒng)只需要擁有一個的全局對象杂腰,這樣有利于我們協(xié)調(diào)系統(tǒng)整體的行為垃你,比如想獲得[UIApplication sharedApplication];任何地方調(diào)用都可以得到 UIApplication的對象,這個對象是全局唯一的。 觀察者模式: 當(dāng)一個物體發(fā)生變化時(shí)蜡镶,會通知所有觀察這個物體的觀察者讓其做出反應(yīng)雾袱。實(shí)現(xiàn)起來無非就是把所有觀察者的對象給這個物體,當(dāng)這個物體的發(fā)生改變官还,就會調(diào)用遍歷所有觀察者的對象調(diào)用觀察者的方法從而達(dá)到通知觀察者的目的芹橡。 工廠模式:
15 淺復(fù)制和深復(fù)制的區(qū)別?
答:淺層復(fù)制:只復(fù)制指向?qū)ο蟮闹羔槪粡?fù)制引用對象本身望伦。 深層復(fù)制:復(fù)制引用對象本身林说。 意思就是說我有個A對象,復(fù)制一份后得到A_copy對象后屯伞,對于淺復(fù)制來說腿箩,A和A_copy指向的是同一個內(nèi)存資源,復(fù)制的只不過是是一個指針劣摇,對象本身資源 還是只有一份珠移,那如果我們對A_copy執(zhí)行了修改操作,那么發(fā)現(xiàn)A引用的對象同樣被修改,這其實(shí)違背了我們復(fù)制拷貝的一個思想末融。深復(fù)制就好理解了,內(nèi)存中存在了 兩份獨(dú)立對象本身钧惧。 用網(wǎng)上一哥們通俗的話將就是: 淺復(fù)制好比你和你的影子,你完蛋勾习,你的影子也完蛋 深復(fù)制好比你和你的克隆人浓瞪,你完蛋,你的克隆人還活著巧婶。 16. 類別的作用?繼承和類別在實(shí)現(xiàn)中有何區(qū)別? 答:category 可以在不獲悉乾颁,不改變原來代碼的情況下往里面添加新的方法,只能添加艺栈,不能刪除修改英岭,并且如果類別和原來類中的方法產(chǎn)生名稱沖突,則類別將覆蓋原來的方法眼滤,因?yàn)轭悇e具有更高的優(yōu)先級巴席。 類別主要有3個作用: 1).將類的實(shí)現(xiàn)分散到多個不同文件或多個不同框架中。 2).創(chuàng)建對私有方法的前向引用诅需。 3).向?qū)ο筇砑臃钦絽f(xié)議漾唉。 繼承可以增加,修改或者刪除方法堰塌,并且可以增加屬性赵刑。 17. 類別和類擴(kuò)展的區(qū)別。 答:category和extensions的不同在于 后者可以添加屬性场刑。另外后者添加的方法是必須要實(shí)現(xiàn)的般此。 extensions可以認(rèn)為是一個私有的Category。 18. oc中的協(xié)議和java中的接口概念有何不同? 答:OC中的代理有2層含義,官方定義為 formal和informal protocol铐懊。前者和Java接口一樣邀桑。 informal protocol中的方法屬于設(shè)計(jì)模式考慮范疇,不是必須實(shí)現(xiàn)的科乎,但是如果有實(shí)現(xiàn)壁畸,就會改變類的屬性。 其實(shí)關(guān)于正式協(xié)議茅茂,類別和非正式協(xié)議我很早前學(xué)習(xí)的時(shí)候大致看過捏萍,也寫在了學(xué)習(xí)教程里 “非正式協(xié)議概念其實(shí)就是類別的另一種表達(dá)方式“這里有一些你可能希望實(shí)現(xiàn)的方法,你可以使用他們更好的完成工作”空闲。 這個意思是令杈,這些是可選的。比如我門要一個更好的方法碴倾,我們就會申明一個這樣的類別去實(shí)現(xiàn)逗噩。然后你在后期可以直接使用這些更好的方法。 這么看影斑,總覺得類別這玩意兒有點(diǎn)像協(xié)議的可選協(xié)議给赞。” 現(xiàn)在來看矫户,其實(shí)protocal已經(jīng)開始對兩者都統(tǒng)一和規(guī)范起來操作,因?yàn)橘Y料中說“非正式協(xié)議使用interface修飾“残邀, 現(xiàn)在我們看到協(xié)議中兩個修飾詞:“必須實(shí)現(xiàn)(@requied)”和“可選實(shí)現(xiàn)(@optional)”皆辽。 19. 什么是KVO和KVC? 答:KVC:鍵 – 值編碼是一種間接訪問對象的屬性使用字符串來標(biāo)識屬性,而不是通過調(diào)用存取方法芥挣,直接或通過實(shí)例變量訪問的機(jī)制驱闷。 很多情況下可以簡化程序代碼。apple文檔其實(shí)給了一個很好的例子空免。 KVO:鍵值觀察機(jī)制空另,他提供了觀察某一屬性變化的方法,極大的簡化了代碼蹋砚。 具體用看到嗯哼用到過的一個地方是對于按鈕點(diǎn)擊變化狀態(tài)的的監(jiān)控扼菠。 比如我自定義的一個button 對于系統(tǒng)是根據(jù)keypath去取的到相應(yīng)的值發(fā)生改變,理論上來說是和kvc機(jī)制的道理是一樣的坝咐。 對于kvc機(jī)制如何通過key尋找到value: “當(dāng)通過KVC調(diào)用對象時(shí)循榆,比如:[self valueForKey:@”someKey”]時(shí),程序會自動試圖通過幾種不同的方式解析這個調(diào)用墨坚。首先查找對象是否帶有 someKey 這個方法秧饮,如果沒找到,會繼續(xù)查找對象是否帶有someKey這個實(shí)例變量(iVar),如果還沒有找到盗尸,程序會繼續(xù)試圖調(diào)用 -(id) valueForUndefinedKey:這個方法柑船。如果這個方法還是沒有被實(shí)現(xiàn)的話,程序會拋出一個NSUndefinedKeyException異常錯誤泼各。 (cocoachina.com注:Key-Value Coding查找方法的時(shí)候椎组,不僅僅會查找someKey這個方法,還會查找getsomeKey這個方法历恐,前面加一個get寸癌,或者_(dá)someKey以及_getsomeKey這幾種形式。同時(shí)弱贼,查找實(shí)例變量的時(shí)候也會不僅僅查找someKey這個變量蒸苇,也會查找_someKey這個變量是否存在。) 設(shè)計(jì)valueForUndefinedKey:方法的主要目的是當(dāng)你使用-(id)valueForKey方法從對象中請求值時(shí)吮旅,對象能夠在錯誤發(fā)生前溪烤,有最后的機(jī)會響應(yīng)這個請求。這樣做有很多好處庇勃,下面的兩個例子說明了這樣做的好處檬嘀。“ 來至cocoa责嚷,這個說法應(yīng)該挺有道理鸳兽。 因?yàn)槲覀冎纀utton卻是存在一個highlighted實(shí)例變量.因此為何上面我們只是add一個相關(guān)的keypath就行了, 可以按照kvc查找的邏輯理解罕拂,就說的過去了揍异。 20. 代理的作用? 答:代理的目的是改變或傳遞控制鏈。允許一個類在某些特定時(shí)刻通知到其他類爆班,而不需要獲取到那些類的指針衷掷。可以減少框架復(fù)雜度柿菩。 另外一點(diǎn)戚嗅,代理可以理解為java中的回調(diào)監(jiān)聽機(jī)制的一種類似。 21. oc中可修改和不可以修改類型枢舶。 答:可修改不可修改的集合類懦胞。這個我個人簡單理解就是可動態(tài)添加修改和不可動態(tài)添加修改一樣。 比如NSArray和NSMutableArray祟辟。前者在初始化后的內(nèi)存控件就是固定不可變的医瘫,后者可以添加等,可以動態(tài)申請新的內(nèi)存空間旧困。 22. 我們說的oc是動態(tài)運(yùn)行時(shí)語言是什么意思? 答:多態(tài)醇份。 主要是將數(shù)據(jù)類型的確定由編譯時(shí)稼锅,推遲到了運(yùn)行時(shí)。 這個問題其實(shí)淺涉及到兩個概念僚纷,運(yùn)行時(shí)和多態(tài)矩距。 簡單來說,運(yùn)行時(shí)機(jī)制使我們直到運(yùn)行時(shí)才去決定一個對象的類別怖竭,以及調(diào)用該類別對象指定方法锥债。 多態(tài):不同對象以自己的方式響應(yīng)相同的消息的能力叫做多態(tài)。意思就是假設(shè)生物類(life)都用有一個相同的方法-eat; 那人類屬于生物痊臭,豬也屬于生物哮肚,都繼承了life后,實(shí)現(xiàn)各自的eat广匙,但是調(diào)用是我們只需調(diào)用各自的eat方法允趟。 也就是不同的對象以自己的方式響應(yīng)了相同的消息(響應(yīng)了eat這個選擇器)。 因此也可以說鸦致,運(yùn)行時(shí)機(jī)制是多態(tài)的基礎(chǔ)?~~~ 23. 通知和協(xié)議的不同之處? 答:協(xié)議有控制鏈(has-a)的關(guān)系潮剪,通知沒有。 首先我一開始也不太明白分唾,什么叫控制鏈(專業(yè)術(shù)語了~)抗碰。但是簡單分析下通知和代理的行為模式,我們大致可以有自己的理解 簡單來說绽乔,通知的話弧蝇,它可以一對多坦辟,一條消息可以發(fā)送給多個消息接受者。 代理按我們的理解潦匈,到不是直接說不能一對多临扮,比如我們知道的明星經(jīng)濟(jì)代理人,很多時(shí)候一個經(jīng)濟(jì)人負(fù)責(zé)好幾個明星的事務(wù)涕蜂。 只是對于不同明星間,代理的事物對象都是不一樣的,一一對應(yīng)睹逃,不可能說明天要處理A明星要一個發(fā)布會,代理人發(fā)出處理發(fā)布會的消息后祷肯,別稱B的 發(fā)布會了沉填。但是通知就不一樣,他只關(guān)心發(fā)出通知佑笋,而不關(guān)心多少接收到感興趣要處理翼闹。 因此控制鏈(has-a從英語單詞大致可以看出,單一擁有和可控制的對應(yīng)關(guān)系蒋纬。 24. 什么是推送消息? 答:推送通知更是一種技術(shù)猎荠。 簡單點(diǎn)就是客戶端獲取資源的一種手段坚弱。 普通情況下,都是客戶端主動的pull关摇。 推送則是服務(wù)器端主動push荒叶。 測試push的實(shí)現(xiàn)可以查看該博文。 25. 關(guān)于多態(tài)性 答:多態(tài)输虱,子類指針可以賦值給父類些楣。 這個題目其實(shí)可以出到一切面向?qū)ο笳Z言中, 因此關(guān)于多態(tài)宪睹,繼承和封裝基本最好都有個自我意識的理解愁茁,也并非一定要把書上資料上寫的能背出來 26. 對于單例的理解 答:在objective-c中要實(shí)現(xiàn)一個單例類,至少需要做以下四個步驟: 1).為單例對象實(shí)現(xiàn)一個靜態(tài)實(shí)例亭病,并初始化鹅很,然后設(shè)置成nil, 2).實(shí)現(xiàn)一個實(shí)例構(gòu)造方法檢查上面聲明的靜態(tài)實(shí)例是否為nil命贴,如果是則新建并返回一個本類的實(shí)例道宅, 3).重寫allocWithZone方法,用來保證其他人直接使用alloc和init試圖獲得一個新實(shí)力的時(shí)候不產(chǎn)生一個新實(shí)例胸蛛, 4).適當(dāng)實(shí)現(xiàn)allocWitheZone污茵,copyWithZone,release和autorelease葬项。 27. 說說響應(yīng)鏈 答: 事件響應(yīng)鏈泞当。包括點(diǎn)擊事件,畫面刷新事件等民珍。在視圖棧內(nèi)從上至下襟士,或者從下之上傳播。 可以說點(diǎn)事件的分發(fā)嚷量,傳遞以及處理陋桂。具體可以去看下touch事件這塊。因?yàn)閱柕奶橄蠡?嚴(yán)重懷疑題目出到越后面就越籠統(tǒng)蝶溶。 可以從責(zé)任鏈模式嗜历,來講通過事件響應(yīng)鏈處理,其擁有的擴(kuò)展性 28. frame和bounds有什么不同? 答:frame指的是:該view在父view坐標(biāo)系統(tǒng)中的位置和大小抖所。(參照點(diǎn)是父親的坐標(biāo)系統(tǒng)) bounds指的是:該view在本身坐標(biāo)系統(tǒng)中 的位置和大小梨州。(參照點(diǎn)是本身坐標(biāo)系統(tǒng)) 29. 方法和選擇器有何不同? 答:selector是一個方法的名字,method是一個組合體田轧,包含了名字和實(shí)現(xiàn). 詳情可以看apple文檔暴匠。 30. OC的垃圾回收機(jī)制? 答: OC2.0有Garbage collection,但是iOS平臺不提供傻粘。 一般我們了解的objective-c對于內(nèi)存管理都是手動操作的每窖,但是也有自動釋放池帮掉。 但是差了大部分資料,貌似不要和arc機(jī)制搞混就好了岛请。 31. NSOperation queue? 答:存放NSOperation的集合類旭寿。 操作和操作隊(duì)列,基本可以看成java中的線程和線程池的概念崇败。用于處理ios多線程開發(fā)的問題盅称。 網(wǎng)上部分資料提到一點(diǎn)是,雖然是queue后室,但是卻并不是帶有隊(duì)列的概念缩膝,放入的操作并非是按照嚴(yán)格的先進(jìn)現(xiàn)出。 這邊又有個疑點(diǎn)是岸霹,對于隊(duì)列來說疾层,先進(jìn)先出的概念是Afunc添加進(jìn)隊(duì)列,Bfunc緊跟著也進(jìn)入隊(duì)列贡避,Afunc先執(zhí)行這個是必然的痛黎, 但是Bfunc是等Afunc完全操作完以后,B才開始啟動并且執(zhí)行刮吧,因此隊(duì)列的概念離亂上有點(diǎn)違背了多線程處理這個概念湖饱。 但是轉(zhuǎn)念一想其實(shí)可以參考銀行的取票和叫號系統(tǒng)。 因此對于A比B先排隊(duì)取票但是B率先執(zhí)行完操作杀捻,我們亦然可以感性認(rèn)為這還是一個隊(duì)列井厌。 但是后來看到一票關(guān)于這操作隊(duì)列話題的文章,其中有一句提到 “因?yàn)閮蓚€操作提交的時(shí)間間隔很近致讥,線程池中的線程仅仆,誰先啟動是不定的」父ぃ” 瞬間覺得這個queue名字有點(diǎn)忽悠人了墓拜,還不如pool~ 綜合一點(diǎn),我們知道他可以比較大的用處在于可以幫組多線程編程就好了请契。 32. 什么是延遲加載? 答:懶漢模式撮弧,只在用到的時(shí)候才去初始化。 也可以理解成延時(shí)加載姚糊。 我覺得最好也最簡單的一個列子就是tableView中圖片的加載顯示了。 一個延時(shí)載授舟,避免內(nèi)存過高救恨,一個異步加載,避免線程堵塞释树。 33. 是否在一個視圖控制器中嵌入兩個tableview控制器? 答:一個視圖控制只提供了一個View視圖肠槽,理論上一個tableViewController也不能放吧擎淤, 只能說可以嵌入一個tableview視圖。當(dāng)然秸仙,題目本身也有歧義嘴拢,如果不是我們定性思維認(rèn)為的UIViewController,而是宏觀的表示視圖控制者寂纪,那我們倒是可以把其看成一個視圖控制者席吴,它可以控制多個視圖控制器,比如TabbarController那樣的感覺捞蛋。 34. 一個tableView是否可以關(guān)聯(lián)兩個不同的數(shù)據(jù)源?你會怎么處理? 答:首先我們從代碼來看孝冒,數(shù)據(jù)源如何關(guān)聯(lián)上的,其實(shí)是在數(shù)據(jù)源關(guān)聯(lián)的代理方法里實(shí)現(xiàn)的拟杉。 因此我們并不關(guān)心如何去關(guān)聯(lián)他庄涡,他怎么關(guān)聯(lián)上,方法只是讓我返回根據(jù)自己的需要去設(shè)置如相關(guān)的數(shù)據(jù)源搬设。 因此穴店,我覺得可以設(shè)置多個數(shù)據(jù)源啊,但是有個問題是拿穴,你這是想干嘛呢?想讓列表如何顯示泣洞,不同的數(shù)據(jù)源分區(qū)塊顯示? 35. 什么時(shí)候使用NSMutableArray,什么時(shí)候使用NSArray? 答:當(dāng)數(shù)組在程序運(yùn)行時(shí)贞言,需要不斷變化的斜棚,使用NSMutableArray,當(dāng)數(shù)組在初始化后该窗,便不再改變的弟蚀,使用NSArray。需要指出的是酗失,使用NSArray只表明的是該數(shù)組在運(yùn)行時(shí)不發(fā)生改變义钉,即不能往NSAarry的數(shù)組里新增和刪除元素,但不表明其數(shù)組內(nèi)的元素的內(nèi)容不能發(fā)生改變规肴。NSArray是線程安全的捶闸,NSMutableArray不是線程安全的,多線程使用到NSMutableArray需要注意拖刃。 36. 給出委托方法的實(shí)例删壮,并且說出UITableVIew的Data Source方法 答:CocoaTouch框架中用到了大量委托,其中UITableViewDelegate就是委托機(jī)制的典型應(yīng)用兑牡,是一個典型的使用委托來實(shí)現(xiàn)適配器模式央碟,其中UITableViewDelegate協(xié)議是目標(biāo),tableview是適配器均函,實(shí)現(xiàn)UITableViewDelegate協(xié)議亿虽,并將自身設(shè)置為talbeview的delegate的對象菱涤,是被適配器,一般情況下該對象是UITableViewController洛勉。 UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 37. 在應(yīng)用中可以創(chuàng)建多少autorelease對象粘秆,是否有限制? 答案:無 38. 如果我們不創(chuàng)建內(nèi)存池,是否有內(nèi)存池提供給我們? 答:界面線程維護(hù)著自己的內(nèi)存池收毫,用戶自己創(chuàng)建的數(shù)據(jù)線程攻走,則需要創(chuàng)建該線程的內(nèi)存池 39. 什么時(shí)候需要在程序中創(chuàng)建內(nèi)存池? 答:用戶自己創(chuàng)建的數(shù)據(jù)線程,則需要創(chuàng)建該線程的內(nèi)存池 40. 類NSObject的那些方法經(jīng)常被使用? 答:NSObject是Objetive-C的基類牛哺,其由NSObject類及一系列協(xié)議構(gòu)成陋气。 其中類方法alloc、class引润、 description 對象方法init巩趁、dealloc、– performSelector:withObject:afterDelay:等經(jīng)常被使用 41. 什么是簡便構(gòu)造方法? 答:簡便構(gòu)造方法一般由CocoaTouch框架提供淳附,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt: Foundation下大部分類均有簡便構(gòu)造方法议慰,我們可以通過簡便構(gòu)造方法,獲得系統(tǒng)給我們創(chuàng)建好的對象奴曙,并且不需要手動釋放别凹。 42. 如何使用Xcode設(shè)計(jì)通用應(yīng)用? 答:使用MVC模式設(shè)計(jì)應(yīng)用,其中Model層完成脫離界面洽糟,即在Model層炉菲,其是可運(yùn)行在任何設(shè)備上,在controller層坤溃,根據(jù)iPhone與iPad(獨(dú)有UISplitViewController)的不同特點(diǎn)選擇不同的viewController對象拍霜。在View層,可根據(jù)現(xiàn)實(shí)要求薪介,來設(shè)計(jì)祠饺,其中以xib文件設(shè)計(jì)時(shí),其設(shè)置其為universal汁政。 43. UIView的動畫效果有那些? 答:有很多道偷,如 UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUpUIViewAnimationOptionTransitionCurlDown 44. 在iPhone應(yīng)用中如何保存數(shù)據(jù)? 答:有以下幾種保存機(jī)制: 1).通過web服務(wù),保存在服務(wù)器上 2).通過NSCoder固化機(jī)制记劈,將對象保存在文件中 3).通過SQlite或CoreData保存在文件數(shù)據(jù)庫中 45. 什么是coredata? 答:coredata是蘋果提供一套數(shù)據(jù)保存框架勺鸦,其基于SQlite 46. 什么是NSManagedObject模型? 答:NSManagedObject是NSObject的子類 ,也是coredata的重要組成部分目木,它是一個通用的類,實(shí)現(xiàn)了core data 模型層所需的基本功能祝旷,用戶可通過子類化NSManagedObject,建立自己的數(shù)據(jù)模型。 47. 什么是NSManagedobjectContext? 答:NSManagedobjectContext對象負(fù)責(zé)應(yīng)用和數(shù)據(jù)庫之間的交互怀跛。 48. 什么是謂詞? 答:謂詞是通過NSPredicate,是通過給定的邏輯條件作為約束條件柄冲,完成對數(shù)據(jù)的篩選吻谋。 49. 和coredata一起有哪幾種持久化存儲機(jī)制? 答:存入到文件、 存入到NSUserDefaults(系統(tǒng)plist文件中)现横、存入到Sqlite文件數(shù)據(jù)庫 50. 談?wù)剬lock 的理解?并寫出一個使用Block執(zhí)行UIVew動畫? 答:Block是可以獲取其他函數(shù)局部變量的匿名函數(shù)漓拾,其不但方便開發(fā),并且可以大幅提高應(yīng)用的執(zhí)行效率(多核心CPU可直接處理Block指令) 51. 寫出上面代碼的Block的定義戒祠。 答: 52. 試著使用+ beginAnimations:context:以及上述Block的定義骇两,寫出一個可以完成 操作的函數(shù)執(zhí)行部分 答案:無 53. 做過的項(xiàng)目是否涉及網(wǎng)絡(luò)訪問功能,使用什么對象完成網(wǎng)絡(luò)功能? 答:ASIHTTPRequest與NSURLConnection 54. 簡單介紹下NSURLConnection類及+ sendSynchronousRequest:returningResponse:error:與– initWithRequest:delegate:兩個方法的區(qū)別? 答: NSURLConnection主要用于網(wǎng)絡(luò)訪問姜盈,其中+ sendSynchronousRequest:returningResponse:error:是同步訪問數(shù)據(jù)低千,即當(dāng)前線程會阻塞,并等待request的返回的response馏颂,而– initWithRequest:delegate:使用的是異步加載示血,當(dāng)其完成網(wǎng)絡(luò)訪問后,會通過delegate回到主線程救拉,并其委托的對象难审。 55. 多線程是什么 答: 多線程是個復(fù)雜的概念,按字面意思是同步完成多項(xiàng)任務(wù)亿絮,提高了資源的使用效率告喊,從硬件、操作系統(tǒng)派昧、應(yīng)用軟件不同的角度去看黔姜,多線程被賦予不同的內(nèi)涵,對于硬件斗锭,現(xiàn)在市面上多數(shù)的CPU都是多核的地淀,多核的CPU運(yùn)算多線程更為出色;從操作系統(tǒng)角度,是多任務(wù)岖是,現(xiàn)在用的主流操作系統(tǒng)都是多任務(wù)的帮毁,可以一邊聽歌、一邊寫博客;對于應(yīng)用來說豺撑,多線程可以讓應(yīng)用有更快的回應(yīng)烈疚,可以在網(wǎng)絡(luò)下載時(shí),同時(shí)響應(yīng)用戶的觸摸操作聪轿。在iOS應(yīng)用中爷肝,對多線程最初的理解,就是并發(fā),它的含義是原來先做燒水,再摘菜肢础,再炒菜的工作跳昼,會變成燒水的同時(shí)去摘菜,最后去炒菜夹抗。 56. iOS 中的多線程 答: iOS中的多線程,是Cocoa框架下的多線程纵竖,通過Cocoa的封裝漠烧,可以讓我們更為方便的使用線程,做過C++的同學(xué)可能會對線程有更多的理解靡砌,比如線程的創(chuàng)立已脓,信號量、共享變量有認(rèn)識通殃,Cocoa框架下會方便很多度液,它對線程做了封裝,有些封裝邓了,可以讓我們創(chuàng)建的對象恨诱,本身便擁有線程,也就是線程的對象化抽象骗炉,從而減少我們的工程照宝,提供程序的健壯性。 GCD是(Grand Central Dispatch)的縮寫 句葵,從系統(tǒng)級別提供的一個易用地多線程類庫厕鹃,具有運(yùn)行時(shí)的特點(diǎn),能充分利用多核心硬件乍丈。GCD的API接口為C語言的函數(shù)剂碴,函數(shù)參數(shù)中多數(shù)有Block,關(guān)于Block的使用參看這里轻专,為我們提供強(qiáng)大的“接口”忆矛,對于GCD的使用參見本文 NSOperation與Queue NSOperation是一個抽象類,它封裝了線程的細(xì)節(jié)實(shí)現(xiàn)请垛,我們可以通過子類化該對象催训,加上NSQueue來同面向?qū)ο蟮乃季S,管理多線程程序宗收。具體可參看這里:一個基于NSOperation的多線程網(wǎng)絡(luò)訪問的項(xiàng)目漫拭。 NSThread NSThread是一個控制線程執(zhí)行的對象,它不如NSOperation抽象混稽,通過它我們可以方便的得到一個線程采驻,并控制它审胚。但NSThread的線程之間的并發(fā)控制,是需要我們自己來控制的礼旅,可以通過NSCondition實(shí)現(xiàn)膳叨。 參看 iOS多線程編程之NSThread的使用 其他多線程 在Cocoa的框架下,通知各淀、Timer和異步函數(shù)等都有使用多線程懒鉴,(待補(bǔ)充). 57. 在項(xiàng)目什么時(shí)候選擇使用GCD,什么時(shí)候選擇NSOperation? 答: 項(xiàng)目中使用NSOperation的優(yōu)點(diǎn)是NSOperation是對線程的高度抽象碎浇,在項(xiàng)目中使用它,會使項(xiàng)目的程序結(jié)構(gòu)更好璃俗,子類化NSOperation的設(shè)計(jì)思路奴璃,是具有面向?qū)ο蟮膬?yōu)點(diǎn)(復(fù)用、封裝)城豁,使得實(shí)現(xiàn)是多線程支持苟穆,而接口簡單,建議在復(fù)雜項(xiàng)目中使用唱星。 項(xiàng)目中使用GCD的優(yōu)點(diǎn)是GCD本身非常簡單雳旅、易用,對于不復(fù)雜的多線程操作间聊,會節(jié)省代碼量攒盈,而Block參數(shù)的使用,會是代碼更為易讀哎榴,建議在簡單項(xiàng)目中使用型豁。 58. 什么是block 答: 對于閉包(block),有很多定義,其中閉包就是能夠讀取其它函數(shù)內(nèi)部變量的函數(shù)尚蝌,這個定義即接近本質(zhì)又較好理解迎变。對于剛接觸Block的同學(xué),會覺得有些繞飘言,因?yàn)槲覀兞?xí)慣寫這樣的程序main(){ funA();} funA(){funB();} funB(){…..}; 就是函數(shù)main調(diào)用函數(shù)A衣形,函數(shù)A調(diào)用函數(shù)B… 函數(shù)們依次順序執(zhí)行,但現(xiàn)實(shí)中不全是這樣的姿鸿,例如項(xiàng)目經(jīng)理M谆吴,手下有3個程序員A、B般妙、C纪铺,當(dāng)他給程序員A安排實(shí)現(xiàn)功能F1時(shí),他并不等著A完成之后碟渺,再去安排B去實(shí)現(xiàn)F2鲜锚,而是安排給A功能F1突诬,B功能F2,C功能F3芜繁,然后可能去寫技術(shù)文檔旺隙,而當(dāng)A遇到問題時(shí),他會來找項(xiàng)目經(jīng)理M骏令,當(dāng)B做完時(shí)蔬捷,會通知M,這就是一個異步執(zhí)行的例子榔袋。在這種情形下周拐,Block便可大顯身手,因?yàn)樵陧?xiàng)目經(jīng)理M凰兑,給A安排工作時(shí)妥粟,同時(shí)會告訴A若果遇到困難,如何能找到他報(bào)告問題(例如打他手機(jī)號)吏够,這就是項(xiàng)目經(jīng)理M給A的一個回調(diào)接口勾给,要回掉的操作,比如接到電話锅知,百度查詢后播急,返回網(wǎng)頁內(nèi)容給A,這就是一個Block售睹,在M交待工作時(shí)桩警,已經(jīng)定義好,并且取得了F1的任務(wù)號(局部變量)侣姆,卻是在當(dāng)A遇到問題時(shí)生真,才調(diào)用執(zhí)行,跨函數(shù)在項(xiàng)目經(jīng)理M查詢百度捺宗,獲得結(jié)果后回調(diào)該block柱蟀。 59. block 實(shí)現(xiàn)原理 答: Objective-C是對C語言的擴(kuò)展,block的實(shí)現(xiàn)是基于指針和函數(shù)指針蚜厉。 從計(jì)算語言的發(fā)展长已,最早的goto,高級語言的指針昼牛,到面向?qū)ο笳Z言的block术瓮,從機(jī)器的思維,一步步接近人的思維贰健,以方便開發(fā)人員更為高效胞四、直接的描述出現(xiàn)實(shí)的邏輯(需求)。 使用實(shí)例 cocoaTouch框架下動畫效果的Block的調(diào)用 使用typed聲明block 然后便可用 聲明一個blokc對象伶椿,注意對象屬性設(shè)置為copy辜伟,接到block 參數(shù)時(shí)氓侧,便會自動復(fù)制一份。 __block是一種特殊類型导狡, 使用該關(guān)鍵字聲明的局部變量约巷,可以被block所改變,并且其在原函數(shù)中的值會被改變旱捧。 60.關(guān)于block 答: 面試時(shí)独郎,面試官會先問一些,是否了解block枚赡,是否使用過block氓癌,這些問題相當(dāng)于開場白,往往是下面一系列問題的開始贫橙,所以一定要如實(shí)根據(jù)自己的情況回答顽铸。 1). 使用block和使用delegate完成委托模式有什么優(yōu)點(diǎn)? 首先要了解什么是委托模式,委托模式在iOS中大量應(yīng)用料皇,其在設(shè)計(jì)模式中是適配器模式中的對象適配器,Objective-C中使用id類型指向一切對象星压,使委托模式更為簡潔践剂。了解委托模式的細(xì)節(jié): iOS設(shè)計(jì)模式—-委托模式 使用block實(shí)現(xiàn)委托模式,其優(yōu)點(diǎn)是回調(diào)的block代碼塊定義在委托對象函數(shù)內(nèi)部娜膘,使代碼更為緊湊; 適配對象不再需要實(shí)現(xiàn)具體某個protocol逊脯,代碼更為簡潔。 2). 多線程與block GCD與Block 使用 dispatch_async 系列方法竣贪,可以以指定的方式執(zhí)行block GCD編程實(shí)例 dispatch_async的完整定義 功能:在指定的隊(duì)列里提交一個異步執(zhí)行的block军洼,不阻塞當(dāng)前線程 通過queue來控制block執(zhí)行的線程。主線程執(zhí)行前文定義的 finishBlock對象 62.談?wù)凮bject-C的內(nèi)存管理方式及過程演怎? 答: 1).當(dāng)你使用new,alloc和copy方法創(chuàng)建一個對象時(shí),該對象的保留計(jì)數(shù)器值為1.當(dāng)你不再使用該對象時(shí),你要負(fù)責(zé)向該對象發(fā)送一條release或autorelease消息.這樣,該對象將在使用壽命結(jié)束時(shí)被銷毀. 2).當(dāng)你通過任何其他方法獲得一個對象時(shí),則假設(shè)該對象的保留計(jì)數(shù)器值為1,而且已經(jīng)被設(shè)置為自動釋放,你不需要執(zhí)行任何操作來確保該對象被清理.如果你打算在一段時(shí)間內(nèi)擁有該對象,則需要保留它并確保在操作完成時(shí)釋放它. 3).如果你保留了某個對象,你需要(最終)釋放或自動釋放該對象.必須保持retain方法和release方法的使用次數(shù)相等. 63.Object-C有私有方法嗎匕争?私有變量呢? 答: objective-c – 類里面的方法只有兩種, 靜態(tài)方法和實(shí)例方法. 這似乎就不是完整的面向?qū)ο罅?按照OO的原則就是一個對象只暴露有用的東西. 如果沒有了私有方法的話, 對于一些小范圍的代碼重用就不那么順手了. 在類里面聲名一個私有方法 @private可以用來修飾私有變量 在Objective‐C中爷耀,所有實(shí)例變量默認(rèn)都是私有的甘桑,所有實(shí)例方法默認(rèn)都是公有的 64.Object-C有多繼承嗎?沒有的話用什么代替歹叮?cocoa 中所有的類都是NSObject 的子類 答: 多繼承在這里是用protocol 委托代理 來實(shí)現(xiàn)的 你不用去考慮繁瑣的多繼承 ,虛基類的概念. ood的多態(tài)特性 在 obj-c 中通過委托來實(shí)現(xiàn). 65.內(nèi)存管理 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的一個自動釋放的值庸汗,或傳遞一個基本數(shù)據(jù)類型(NSInteger惫确,NSString)時(shí):你或希望將對象2進(jìn)行retain,以防止它在被使用之前就被自動釋放掉蚯舱。但是在retain后改化,一定要在適當(dāng)?shù)臅r(shí)候進(jìn)行釋放。 關(guān)于索引計(jì)數(shù)(Reference Counting)的問題 retain值 = 索引計(jì)數(shù)(Reference Counting) NSArray對象會retain(retain值加一)任何數(shù)組中的對象枉昏。當(dāng)NSArray被卸載(dealloc)的時(shí)候陈肛,所有數(shù)組中的對象會 被 執(zhí)行一次釋放(retain值減一)。不僅僅是NSArray兄裂,任何收集類(Collection Classes)都執(zhí)行類似操作句旱。例如 NSDictionary,甚至UINavigationController晰奖。 Alloc/init建立的對象谈撒,索引計(jì)數(shù)為1。無需將其再次retain匾南。 [NSArray array]和[NSDate date]等“方法”建立一個索引計(jì)數(shù)為1的對象啃匿,但是也是一個自動釋放對象。所以是本地臨時(shí)對象蛆楞,那么無所謂了溯乒。如果是打算在全Class中使用的變量(iVar),則必須retain它豹爹。 缺省的類方法返回值都被執(zhí)行了“自動釋放”方法裆悄。(*如上中的NSArray) 在類中的卸載方法“dealloc”中,release所有未被平衡的NS對象帅戒。(*所有未被autorelease灯帮,而retain值為1的) 66. C和obj-c 如何混用 答: 1).obj-c的編譯器處理后綴為m的文件時(shí),可以識別obj-c和c的代碼逻住,處理mm文件可以識別obj-c,c,c++代碼钟哥,但cpp文件必須只能用c/c++代碼,而且cpp文件include的頭文件中瞎访,也不能出現(xiàn)obj-c的代碼腻贰,因?yàn)閏pp只是cpp 2).在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是問題 3).在cpp中混用obj-c其實(shí)就是使用obj-c編寫的模塊是我們想要的扒秸。 如果模塊以類實(shí)現(xiàn)播演,那么要按照cpp class的標(biāo)準(zhǔn)寫類的定義冀瓦,頭文件中不能出現(xiàn)obj-c的東西,包括#import cocoa的写烤。實(shí)現(xiàn)文件中翼闽,即類的實(shí)現(xiàn)代碼中可以使用obj-c的東西,可以import,只是后綴是mm洲炊。 如果模塊以函數(shù)實(shí)現(xiàn)感局,那么頭文件要按c的格式聲明函數(shù),實(shí)現(xiàn)文件中暂衡,c++函數(shù)內(nèi)部可以用obj-c询微,但后綴還是mm或m。 總結(jié):只要cpp文件和cpp include的文件中不包含obj-c的東西就可以用了狂巢,cpp混用obj-c的關(guān)鍵是使用接口撑毛,而不能直接使用 實(shí)現(xiàn)代 碼,實(shí)際上cpp混用的是obj-c編譯后的o文件唧领,這個東西其實(shí)是無差別的藻雌,所以可以用。obj-c的編譯器支持cpp 67. Objective-C堆和棧的區(qū)別斩个? 答: 管理方式:對于棧來講蹦疑,是由編譯器自動管理,無需我們手工控制萨驶;對于堆來說,釋放工作由程序員控制艇肴,容易產(chǎn)生memory leak腔呜。 申請大小: 棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)再悼,是一塊連續(xù)的內(nèi)存的區(qū)域核畴。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下冲九,棧的大小是2M(也有的說是1M,總之是一個編譯時(shí)就確定的常數(shù)),如果申請的空間超過棧的剩余空間時(shí)渐行,將提示overflow统抬。因 此,能從棧獲得的空間較小灭贷。 堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)温学,是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲的空閑內(nèi)存地址的甚疟,自然是不連續(xù)的仗岖,而鏈表的遍歷方向是由低地址向高地址逃延。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見轧拄,堆獲得的空間比較靈活揽祥,也比較大。 碎片問題:對于堆來講檩电,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù)拄丰,從而造成大量的碎片,使程序效率降低是嗜。對于棧來講愈案,則不會存在這個問題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列鹅搪,他們是如此的一一對應(yīng)站绪,以至于永遠(yuǎn)都不可能有一個內(nèi)存塊從棧中間彈出 分配方式:堆都是動態(tài)分配的,沒有靜態(tài)分配的堆丽柿。棧有2種分配方式:靜態(tài)分配和動態(tài)分配恢准。靜態(tài)分配是編譯器完成的,比如局部變量的分配甫题。動態(tài)分配由alloca函數(shù)進(jìn)行分配馁筐,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由編譯器進(jìn)行釋放坠非,無需我們手工實(shí)現(xiàn)敏沉。 分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會在底層對棧提供支持:分配專門的寄存器存放棧的地址炎码,壓棧出棧都有專門的指令執(zhí)行盟迟,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的潦闲,它的機(jī)制是很復(fù)雜的攒菠。 68. ViewController的didReceiveMemoryWarning怎么被調(diào)用: 答:[supper didReceiveMemoryWarning]; 69.什么時(shí)候用delegate,什么時(shí)候用Notification? 答: delegate針對one-to-one關(guān)系,用于sender接受到reciever的某個功能反饋值歉闰。 notification針對one-to-one/many/none,reciver,用于通知多個object某個事件辖众。 70.用預(yù)處理指令#define聲明一個常數(shù),用以表明1年中有多少秒(忽略閏年問題) 答: define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在這想看到幾件事情: define 語法的基本知識(例如:不能以分號結(jié)束和敬,括號的使用凹炸,等等) 懂得預(yù)處理器將為你計(jì)算常數(shù)表達(dá)式的值,因此昼弟,直接寫出你是如何計(jì)算一年中有多少秒而不是計(jì)算出實(shí)際的值还惠,是更清晰而沒有代價(jià)的。 意識到這個表達(dá)式將使一個16位機(jī)的整型數(shù)溢出-因此要用到長整型符號L,告訴編譯器這個常數(shù)是的長整型數(shù)。 如果你在你的表達(dá)式中用到UL(表示無符號長整型)蚕键,那么你有了一個好的起點(diǎn)救欧。記住,第一印象很重要锣光。 71.寫一個”標(biāo)準(zhǔn)"宏MIN 笆怠,這個宏輸入兩個參數(shù)并返回較小的一個。 答: 這個測試是為下面的目的而設(shè)的: 標(biāo)識#define在宏中應(yīng)用的基本知識誊爹。這是很重要的蹬刷,因?yàn)橹钡角度?inline)操作符變?yōu)闃?biāo)準(zhǔn)C的一部分,宏是方便產(chǎn)生嵌入代碼的唯一方 法频丘, 對于嵌入式系統(tǒng)來說办成,為了能達(dá)到要求的性能,嵌入代碼經(jīng)常是必須的方法搂漠。 三重條件操作符的知識迂卢。這個操作符存在C語言中的原因是它使得編譯器能產(chǎn)生比 if-then-else 更優(yōu)化的代碼,了解這個用法是很重要的桐汤。 懂得在宏中小心地把參數(shù)用括號括起來 我也用這個問題開始討論宏的副作用而克,例如:當(dāng)你寫下面的代碼時(shí)會發(fā)生什么事? 結(jié)果是: 這個表達(dá)式會產(chǎn)生副作用怔毛,指針p會作三次++自增操作员萍。 72.關(guān)鍵字const有什么含意?修飾類呢?static的作用,用于類呢?還有extern c的作用 答: const 意味著"只讀"拣度,下面的聲明都是什么意思碎绎? 前兩個的作用是一樣,a是一個常整型數(shù)抗果。 第三個意味著a是一個指向常整型數(shù)的指針(也就是混卵,整型數(shù)是不可修改的,但指針可以)窖张。 第四個意思a是一個指向整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是可以修改的蚁滋,但指針是不可修改的)宿接。 最后一個意味著a是一個指向常整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是不可修改的辕录,同時(shí)指針也是不可修改的)睦霎。 結(jié)論: 關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上走诞,聲明一個參數(shù)為常量是為了告訴了用戶這個參數(shù)的應(yīng)用目的副女。 如果你曾花很多時(shí)間清理其它人留下的垃圾,你就會很快學(xué)會感謝這點(diǎn)多余的信息蚣旱。(當(dāng)然碑幅,懂得用const的程序員很少會留下的垃圾讓別人來清理的) 通過給優(yōu)化器一些附加的信息戴陡,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù)沟涨,防止其被無意的代碼修改恤批。簡而言之,這樣可以減少bug的出現(xiàn)裹赴。 1).欲阻止一個變量被改變喜庞,可以使用 const 關(guān)鍵字。在定義該 const 變量時(shí)棋返,通常需要對它進(jìn)行初 始化延都,因?yàn)橐院缶蜎]有機(jī)會再去改變它了; 2).對指針來說睛竣,可以指定指針本身為 const晰房,也可以指定指針?biāo)傅臄?shù)據(jù)為 const,或二者同時(shí)指 定為 const酵颁; 3).在一個函數(shù)聲明中嫉你,const 可以修飾形參,表明它是一個輸入?yún)?shù)躏惋,在函數(shù)內(nèi)部不能改變其值幽污; 4).對于類的成員函數(shù),若指定其為 const 類型簿姨,則表明其是一個常函數(shù)距误,不能修改類的成員變量; 5).對于類的成員函數(shù)扁位,有時(shí)候必須指定其返回值為 const 類型准潭,以使得其返回值不為“左值”。 73. 關(guān)鍵字volatile有什么含意?并給出三個不同的例子域仇。 答:一個定義為 volatile的變量是說這變量可能會被意想不到地改變刑然,這樣,編譯器就不會去假設(shè)這個變量的值了暇务。精確地說就是泼掠,優(yōu)化器在用到這個變量時(shí)必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份垦细。 下面是volatile變量的幾個例子: 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器) 一個中斷服務(wù)子程序中會訪問到的非自動變量(Non-automatic variables) 多線程應(yīng)用中被幾個任務(wù)共享的變量 74. 一個參數(shù)既可以是const還可以是volatile嗎择镇? 一個指針可以是volatile 嗎?解釋為什么括改。 答:1).是的腻豌。一個例子是只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖儭K莄onst因?yàn)槌绦虿粦?yīng)該試圖去修改它吝梅。 2).是的虱疏。盡管這并不很常見。一個例子是當(dāng)一個中服務(wù)子程序修該一個指向一個buffer的指針時(shí)憔涉。 75 . static 關(guān)鍵字的作用: 答: 1).函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體订框,不同于 auto 變量,該變量的內(nèi)存只被分配一次兜叨, 因此其值在下次調(diào)用時(shí)仍維持上次的值穿扳; 2).在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問国旷; 3).在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用矛物,這個函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi); 4).在類中的 static 成員變量屬于整個類所擁有跪但,對類的所有對象只有一份拷貝履羞; 5).在類中的 static 成員函數(shù)屬于整個類所擁有,這個函數(shù)不接收 this 指針屡久,因而只能訪問類的static 成員變量忆首。 76. 線程與進(jìn)程的區(qū)別和聯(lián)系? 答: 1). 進(jìn)程和線程都是由操作系統(tǒng)所體會的程序運(yùn)行的基本單元,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對應(yīng)用的并發(fā)性 2). 進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式被环。 3). 進(jìn)程有獨(dú)立的地址空間糙及,一個進(jìn)程崩潰后,在保護(hù)模式下不會對其它進(jìn)程產(chǎn)生影響筛欢,而線程只是一個進(jìn)程中的不同執(zhí)行路徑浸锨。 4.)線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間版姑,一個線程死掉就等于整個進(jìn)程死掉柱搜。所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí)剥险,耗費(fèi)資源較大聪蘸,效率要差一些。 5). 但對于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作表制,只能用線程健爬,不能用進(jìn)程。 77. 列舉幾種進(jìn)程的同步機(jī)制夫凸,并比較其優(yōu)缺點(diǎn)。 答: 原子操作 信號量機(jī)制 自旋鎖 管程阱持,會合夭拌,分布式系統(tǒng) 78. 進(jìn)程之間通信的途徑 答:共享存儲系統(tǒng)消息傳遞系統(tǒng)管道:以文件系統(tǒng)為基礎(chǔ) 79. 進(jìn)程死鎖的原因 答:資源競爭及進(jìn)程推進(jìn)順序非法 80. 死鎖的4個必要條件 答:互斥、請求保持、不可剝奪鸽扁、環(huán)路 81. 死鎖的處理 答:鴕鳥策略蒜绽、預(yù)防策略、避免策略桶现、檢測與解除死鎖 82. cocoa touch框架 答:iPhone OS 應(yīng)用程序的基礎(chǔ) Cocoa Touch 框架重用了許多 Mac 系統(tǒng)的成熟模式躲雅,但是它更多地專注于觸摸的接口和優(yōu)化。 UIKit 為您提供了在 iPhone OS 上實(shí)現(xiàn)圖形骡和,事件驅(qū)動程序的基本工具相赁,其建立在和 Mac OS X 中一樣的 Foundation 框架上,包括文件處理慰于,網(wǎng)絡(luò)钮科,字符串操作等。 Cocoa Touch 具有和 iPhone 用戶接口一致的特殊設(shè)計(jì)婆赠。有了 UIKit绵脯,您可以使用 iPhone OS 上的獨(dú)特的圖形接口控件,按鈕休里,以及全屏視圖的功能蛆挫,您還可以使用加速儀和多點(diǎn)觸摸手勢來控制您的應(yīng)用。 各色俱全的框架 除了UIKit 外妙黍,Cocoa Touch 包含了創(chuàng)建世界一流 iPhone 應(yīng)用程序需要的所有框架悴侵,從三維圖形,到專業(yè)音效废境,甚至提供設(shè)備訪問 API 以控制攝像頭畜挨,或通過 GPS 獲知當(dāng)前位置。 Cocoa Touch 既包含只需要幾行代碼就可以完成全部任務(wù)的強(qiáng)大的 Objective-C 框架噩凹,也在需要時(shí)提供基礎(chǔ)的 C 語言 API 來直接訪問系統(tǒng)巴元。這些框架包括: Core Animation:通過 Core Animation,您就可以通過一個基于組合獨(dú)立圖層的簡單的編程模型來創(chuàng)建豐富的用戶體驗(yàn)驮宴。 Core Audio:Core Audio 是播放逮刨,處理和錄制音頻的專業(yè)技術(shù),能夠輕松為您的應(yīng)用程序添加強(qiáng)大的音頻功能堵泽。 Core Data:提供了一個面向?qū)ο蟮臄?shù)據(jù)管理解決方案修己,它易于使用和理解,甚至可處理任何應(yīng)用或大或小的數(shù)據(jù)模型迎罗。 功能列表:框架分類 下面是 Cocoa Touch 中一小部分可用的框架: 音頻和視頻:Core Audio 睬愤,OpenAL ,Media Library 纹安,AV Foundation 數(shù)據(jù)管理 :Core Data 尤辱,SQLite 圖形和動畫 :Core Animation 砂豌,OpenGL ES ,Quartz 2D 網(wǎng)絡(luò):Bonjour 光督,WebKit 阳距,BSD Sockets 用戶應(yīng)用:Address Book ,Core Location 结借,Map Kit 筐摘,Store Kit 83. 自動釋放池是什么,如何工作 答:當(dāng)您向一個對象發(fā)送一個autorelease消息時(shí),Cocoa就會將該對象的一個引用放入到最新的自動釋放.它仍然是個正當(dāng)?shù)膶ο蟠希虼俗詣俞尫懦囟x的作用域內(nèi)的其它對象可以向它發(fā)送消息咖熟。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動釋放池就會被釋放努隙,池中的所有對象也就被釋放球恤。 84. Objective-C的優(yōu)缺點(diǎn)。 答:objc優(yōu)點(diǎn): 1). Cateogies 2). Posing 3). 動態(tài)識別 4).指標(biāo)計(jì)算 5).彈性訊息傳遞 6).不是一個過度復(fù)雜的 C 衍生語言 7).Objective-C 與 C++ 可混合編程 objc缺點(diǎn): 1).不支援命名空間 2).不支持運(yùn)算符重載 3).不支持多重繼承 4).使用動態(tài)運(yùn)行時(shí)類型荸镊,所有的方法都是函數(shù)調(diào)用咽斧,所以很多編譯時(shí)優(yōu)化方法都用不到。(如內(nèi)聯(lián)函數(shù)等)躬存,性能低劣张惹。 85. sprintf,strcpy,memcpy使用上有什么要注意的地方。 答: 1). sprintf是格式化函數(shù)岭洲。將一段數(shù)據(jù)通過特定的格式宛逗,格式化到一個字符串緩沖區(qū)中去。sprintf格式化的函數(shù)的長度不可控盾剩,有可能格式化后的字符串會超出緩沖區(qū)的大小雷激,造成溢出。 2).strcpy是一個字符串拷貝的函數(shù)告私,它的函數(shù)原型為strcpy(char *dst, const char *src 將src開始的一段字符串拷貝到dst開始的內(nèi)存中去屎暇,結(jié)束的標(biāo)志符號為 ‘\0',由于拷貝的長度不是由我們自己控制的驻粟,所以這個字符串拷貝很容易出錯掀序。 3). memcpy是具備字符串拷貝功能的函數(shù)呀邢,這是一個內(nèi)存拷貝函數(shù),它的函數(shù)原型為memcpy(char dst, const char src, unsigned int len);將長度為len的一段內(nèi)存查近,從src拷貝到dst中去满着,這個函數(shù)的長度可控阿纤。但是會有內(nèi)存疊加的問題甚负。 86. readwrite否淤,readonly,assign沃饶,retain母廷,copy瀑晒,nonatomic 屬性的作用 答:@property是一個屬性訪問聲明,擴(kuò)號內(nèi)支持以下幾個屬性: 1).getter=getterName徘意,setter=setterName,設(shè)置setter與 getter的方法名 2).readwrite,readonly轩褐,設(shè)置可供訪問級別 2).assign椎咧,setter方法直接賦值,不進(jìn)行任何retain操作把介,為了解決原類型與環(huán)循引用問題 3).retain勤讽,setter方法對參數(shù)進(jìn)行release舊值再retain新值,所有實(shí)現(xiàn)都是這個順序(CC上有相關(guān)資料) 4).copy拗踢,setter方法進(jìn)行Copy操作脚牍,與retain處理流程一樣,先舊值release巢墅,再 Copy出新的對象诸狭,retainCount為1。這是為了減少對上下文的依賴而引入的機(jī)制君纫。 5).nonatomic驯遇,非原子性訪問,不加同步蓄髓,多線程并發(fā)訪問會提高性能叉庐。注意,如果不加此屬性会喝,則默認(rèn)是兩個訪問方法都為原子型事務(wù)訪問陡叠。鎖被加到所屬對象實(shí)例級。 87. http和scoket通信的區(qū)別肢执。 答: http是客戶端用http協(xié)議進(jìn)行請求枉阵,發(fā)送請求時(shí)候需要封裝http請求頭,并綁定請求的數(shù)據(jù)蔚万,服務(wù)器一般有web服務(wù)器配合(當(dāng)然也非絕對)岭妖。 http請求方式為客戶端主動發(fā)起請求,服務(wù)器才能給響應(yīng)反璃,一次請求完畢后則斷開連接昵慌,以節(jié)省資源。服務(wù)器不能主動給客戶端響應(yīng)(除非采取http長連接 技術(shù))淮蜈。iphone主要使用類是NSUrlConnection斋攀。 scoket是客戶端跟服務(wù)器直接使用socket“套接字”進(jìn)行連接,并沒有規(guī)定連接后斷開梧田,所以客戶端和服務(wù)器可以保持連接通道淳蔼,雙方 都可以主動發(fā)送數(shù)據(jù)侧蘸。一般在游戲開發(fā)或股票開發(fā)這種要求即時(shí)性很強(qiáng)并且保持發(fā)送數(shù)據(jù)量比較大的場合使用。主要使用類是CFSocketRef鹉梨。 88. TCP和UDP的區(qū)別 答: TCP全稱是Transmission Control Protocol讳癌,中文名為傳輸控制協(xié)議,它可以提供可靠的存皂、面向連接的網(wǎng)絡(luò)數(shù)據(jù)傳遞服務(wù)晌坤。傳輸控制協(xié)議主要包含下列任務(wù)和功能: 確保IP數(shù)據(jù)報(bào)的成功傳遞。 對程序發(fā)送的大塊數(shù)據(jù)進(jìn)行分段和重組旦袋。 確保正確排序及按順序傳遞分段的數(shù)據(jù)骤菠。 通過計(jì)算校驗(yàn)和,進(jìn)行傳輸數(shù)據(jù)的完整性檢查疤孕。 TCP提供的是面向連接的商乎、可靠的數(shù)據(jù)流傳輸,而UDP提供的是非面向連接的祭阀、不可靠的數(shù)據(jù)流傳輸鹉戚。 簡單的說,TCP注重?cái)?shù)據(jù)安全专控,而UDP數(shù)據(jù)傳輸快點(diǎn)崩瓤,但安全性一般 89. 你了解svn,cvs等版本控制工具么? 答: 版本控制 svn,cvs 是兩種版控制的器,需要配套相關(guān)的svn踩官,cvs服務(wù)器却桶。 scm是xcode里配置版本控制的地方。版本控制的原理就是a和b同時(shí)開發(fā)一個項(xiàng)目蔗牡,a寫完當(dāng)天的代碼之后把代碼提交給服務(wù)器颖系,b要做的時(shí)候先從服務(wù)器得到最新版本,就可以接著做辩越。 如果a和b都要提交給服務(wù)器嘁扼,并且同時(shí)修改了同一個方法,就會產(chǎn)生代碼沖突黔攒,如果a先提交趁啸,那么b提交時(shí),服務(wù)器可以提示沖突的代碼督惰,b可以清晰的看到不傅,并做出相應(yīng)的修改或融合后再提交到服務(wù)器。 90. 什么是push赏胚。 答: 客戶端程序留下后門端口访娶,客戶端總是監(jiān)聽針對這個后門的請求,于是 服務(wù)器可以主動像這個端口推送消息觉阅。 91. 靜態(tài)鏈接庫 答:此為.a文件崖疤,相當(dāng)于java里的jar包秘车,把一些類編譯到一個包中,在不同的工程中如果導(dǎo)入此文件就可以使用里面的類劫哼,具體使用依然是#import “ xx.h”叮趴。 92. fmmpeg框架 答: 音視頻編解碼框架,內(nèi)部使用UDP協(xié)議針對流媒體開發(fā)权烧,內(nèi)部開辟了六個端口來接受流媒體數(shù)據(jù)疫向,完成快速接受之目的。 93. fmdb框架 答:數(shù)據(jù)庫框架豪嚎,對sqllite的數(shù)據(jù)操作進(jìn)行了封裝,使用著可把精力都放在sql語句上面谈火。 94. 320框架 答: ui框架侈询,導(dǎo)入320工程作為框架包如同添加一個普通框架一樣。cover(open) flower框架 (2d 仿射技術(shù))糯耍,內(nèi)部核心類是CATransform3D. 94. 什么是沙盒模型扔字?哪些操作是屬于私有api范疇? 答:某個iphone工程進(jìn)行文件操作有此工程對應(yīng)的指定的位置,不能逾越温技。 iphone沙箱模型的有四個文件夾documents革为,tmp,app舵鳞,Library震檩,永久數(shù)據(jù)存儲一般放documents文件夾,得到模擬器的路徑的可使用NSHomeDirectory()方法蜓堕。Nsuserdefaults保存的文件在tmp文件夾里抛虏。 95. 在一個對象的方法里面:self.name= “object”;和 name =”object” 有什么不同嗎? 答:self.name =”object”:會調(diào)用對象的setName()方法套才; name = “object”:會直接把object賦值給當(dāng)前對象的name屬性迂猴。 96. 請簡要說明viewDidLoad和viewDidUnload何時(shí)調(diào)用 答:viewDidLoad在view從nib文件初始化時(shí)調(diào)用,loadView在controller的view為nil時(shí)調(diào)用背伴。此方法在編程實(shí)現(xiàn)view時(shí)調(diào)用沸毁,view控制器默認(rèn)會注冊memory warning notification,當(dāng)view controller的任何view沒有用的時(shí)候傻寂,viewDidUnload會被調(diào)用息尺,在這里實(shí)現(xiàn)將retain的view release,如果是retain的IBOutlet view 屬性則不要在這里release疾掰,IBOutlet會負(fù)責(zé)release 掷倔。 97. 簡述內(nèi)存分區(qū)情況 答: 1).代碼區(qū):存放函數(shù)二進(jìn)制代碼 2).數(shù)據(jù)區(qū):系統(tǒng)運(yùn)行時(shí)申請內(nèi)存并初始化,系統(tǒng)退出時(shí)由系統(tǒng)釋放个绍。存放全局變量勒葱、靜態(tài)變量浪汪、常量 3).堆區(qū):通過malloc等函數(shù)或new等操作符動態(tài)申請得到,需程序員手動申請和釋放 4).棧區(qū):函數(shù)模塊內(nèi)申請凛虽,函數(shù)結(jié)束時(shí)由系統(tǒng)自動釋放死遭。存放局部變量、函數(shù)參數(shù) 98. 隊(duì)列和棧有什么區(qū)別: 答:隊(duì)列和棧是兩種不同的數(shù)據(jù)容器凯旋。從”數(shù)據(jù)結(jié)構(gòu)”的角度看呀潭,它們都是線性結(jié)構(gòu),即數(shù)據(jù)元素之間的關(guān)系相同至非。 隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)钠署,它在兩端進(jìn)行操作,一端進(jìn)行入隊(duì)列操作荒椭,一端進(jìn)行出列隊(duì)操作谐鼎。 棧是一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),它只能在棧頂進(jìn)行操作趣惠,入棧和出棧都在棧頂操作狸棍。 99. HTTP協(xié)議中,POST和GET的區(qū)別是什么味悄? 答: 1).GET 方法 GET 方法提交數(shù)據(jù)不安全草戈,數(shù)據(jù)置于請求行,客戶端地址欄可見; GET 方法提交的數(shù)據(jù)大小有限 GET 方法不可以設(shè)置書簽 2).POST 方法 POST 方法提交數(shù)據(jù)安全侍瑟,數(shù)據(jù)置于消息主體內(nèi)唐片,客戶端不可見 POST 方法提交的數(shù)據(jù)大小沒有限制 POST 方法可以設(shè)置書簽 100. iOS的系統(tǒng)架構(gòu) 答: iOS的系統(tǒng)架構(gòu)分為( 核心操作系統(tǒng)層 theCore OS layer )、( 核心服務(wù)層theCore Services layer )涨颜、( 媒體層 theMedia layer )和( Cocoa 界面服務(wù)層 the Cocoa Touch layer )四個層次牵触。 101. 控件主要響應(yīng)3種事件 答:1). 基于觸摸的事件 ; 2). 基于值的事件 ; 3).基于編輯的事件。 102. xib文件的構(gòu)成分為哪3個圖標(biāo)咐低?都具有什么功能揽思。 答: File’s Owner 是所有 nib 文件中的每個圖標(biāo),它表示從磁盤加載 nib 文件的對象见擦; First Responder 就是用戶當(dāng)前正在與之交互的對象钉汗; View 顯示用戶界面;完成用戶交互鲤屡;是 UIView 類或其子類损痰。 103. 簡述視圖控件器的生命周期。 答: loadView 盡管不直接調(diào)用該方法酒来,如多手動創(chuàng)建自己的視圖卢未,那么應(yīng)該覆蓋這個方法并將它們賦值給試圖控制器的 view 屬性。 viewDidLoad 只有在視圖控制器將其視圖載入到內(nèi)存之后才調(diào)用該方法,這是執(zhí)行任何其他初始化操作的入口辽社。 viewDidUnload 當(dāng)試圖控制器從內(nèi)存釋放自己的方法的時(shí)候調(diào)用伟墙,用于清楚那些可能已經(jīng)在試圖控制器中創(chuàng)建的對象。 viewVillAppear 當(dāng)試圖將要添加到窗口中并且還不可見的時(shí)候或者上層視圖移出圖層后本視圖變成頂級視圖時(shí)調(diào)用該方法滴铅,用于執(zhí)行諸如改變視圖方向等的操作戳葵。實(shí)現(xiàn)該方法時(shí)確保調(diào)用 [super viewWillAppear: viewDidAppear 當(dāng)視圖添加到窗口中以后或者上層視圖移出圖層后本視圖變成頂級視圖時(shí)調(diào)用,用于放置那些需要在視圖顯示后執(zhí)行的代碼汉匙。確保調(diào)用 [super viewDidAppear:] 拱烁。 104. 動畫有基本類型有哪幾種;表視圖有哪幾種基本樣式噩翠。 答:動畫有兩種基本類型:隱式動畫和顯式動畫戏自。 105. 實(shí)現(xiàn)簡單的表格顯示需要設(shè)置UITableView的什么屬性、實(shí)現(xiàn)什么協(xié)議伤锚? 答:實(shí)現(xiàn)簡單的表格顯示需要設(shè)置 UITableView 的 dataSource 和 delegate 屬性擅笔,實(shí)現(xiàn)UITableViewDataSource 和 UITableViewDelegate 協(xié)議。 106. Cocoa Touch提供了哪幾種Core Animation過渡類型见芹? 答: Cocoa Touch 提供了 4 種 Core Animation 過渡類型,分別為:交叉淡化蠢涝、推擠玄呛、顯示和覆蓋。 107. UIView與CLayer有什么區(qū)別和二? 答: 1).UIView 是 iOS 系統(tǒng)中界面元素的基礎(chǔ)徘铝,所有的界面元素都是繼承自它。它本身完全是由 CoreAnimation 來實(shí)現(xiàn)的惯吕。它真正的繪圖部分惕它,是由一個 CALayer 類來管理。 UIView 本身更像是一個 CALayer 的管理器废登,訪問它的跟繪圖和跟坐標(biāo)有關(guān)的屬性淹魄。 2).UIView 有個重要屬性 layer ,可以返回它的主 CALayer 實(shí)例堡距。 3).UIView 的 CALayer 類似 UIView 的子 View 樹形結(jié)構(gòu)甲锡,也可以向它的 layer 上添加子layer ,來完成某些特殊的表示羽戒。即 CALayer 層是可以嵌套的缤沦。 4).UIView 的 layer 樹形在系統(tǒng)內(nèi)部,被維護(hù)著三份 copy 易稠。分別是邏輯樹缸废,這里是代碼可以操縱的;動畫樹,是一個中間層企量,系統(tǒng)就在這一層上更改屬性测萎,進(jìn)行各種渲染操作;顯示樹梁钾,其內(nèi)容就是當(dāng)前正被顯示在屏幕上得內(nèi)容绳泉。 5).動畫的運(yùn)作:對 UIView 的 subLayer (非主 Layer )屬性進(jìn)行更改,系統(tǒng)將自動進(jìn)行動畫生成姆泻,動畫持續(xù)時(shí)間的缺省值似乎是 0.5 秒零酪。 6).坐標(biāo)系統(tǒng): CALayer 的坐標(biāo)系統(tǒng)比 UIView 多了一個 anchorPoint 屬性,使用CGPoint 結(jié)構(gòu)表示拇勃,值域是 0~1 四苇,是個比例值。這個點(diǎn)是各種圖形變換的坐標(biāo)原點(diǎn)方咆,同時(shí)會更改 layer 的 position 的位置月腋,它的缺省值是 {0.5,0.5} ,即在 layer 的中央瓣赂。 7).渲染:當(dāng)更新層榆骚,改變不能立即顯示在屏幕上。當(dāng)所有的層都準(zhǔn)備好時(shí)煌集,可以調(diào)用setNeedsDisplay 方法來重繪顯示妓肢。 8).變換:要在一個層中添加一個 3D 或仿射變換,可以分別設(shè)置層的 transform 或affineTransform 屬性苫纤。 9).變形: Quartz Core 的渲染能力碉钠,使二維圖像可以被自由操縱,就好像是三維的卷拘。圖像可以在一個三維坐標(biāo)系中以任意角度被旋轉(zhuǎn)喊废,縮放和傾斜。 CATransform3D 的一套方法提供了一些魔術(shù)般的變換效果栗弟。 108. Quatrz 2D的繪圖功能的三個核心概念是什么并簡述其作用污筷。 答:上下文:主要用于描述圖形寫入哪里; 路徑:是在圖層上繪制的內(nèi)容乍赫; 狀態(tài):用于保存配置變換的值颓屑、填充和輪廓, alpha 值等耿焊。 109. iPhone OS主要提供了幾種播放音頻的方法揪惦? 答: SystemSound Services AVAudioPlayer 類 Audio Queue Services OpenAL 110. 使用AVAudioPlayer類調(diào)用哪個框架、使用步驟罗侯? 答: AVFoundation.framework 步驟:配置 AVAudioPlayer 對象器腋; 實(shí)現(xiàn) AVAudioPlayer 類的委托方法熏挎; 控制 AVAudioPlayer 類的對象腔稀; 監(jiān)控音量水平低散; 回放進(jìn)度和拖拽播放桨昙。 111. 有哪幾種手勢通知方法、寫清楚方法名措左? 答: -(void)touchesBegan:(NSSet)touchedwithEvent:(UIEvent)event; -(void)touchesMoved:(NSSet)touched withEvent:(UIEvent)event; -(void)touchesEnded:(NSSet)touchedwithEvent:(UIEvent)event; -(void)touchesCanceled:(NSSet)touchedwithEvent:(UIEvent)event; 112. CFSocket使用有哪幾個步驟依痊。 答:創(chuàng)建 Socket 的上下文;創(chuàng)建 Socket 怎披;配置要訪問的服務(wù)器信息胸嘁;封裝服務(wù)器信息;連接服務(wù)器凉逛; 113. Core Foundation中提供了哪幾種操作Socket的方法性宏? 答: CFNetwork 、 CFSocket 和 BSD Socket 状飞。 114. 解析XML文件有哪幾種方式毫胜? 答:以 DOM 方式解析 XML 文件;以 SAX 方式解析 XML 文件诬辈; 115. ios 平臺怎么做數(shù)據(jù)的持久化?coredata 和sqlite有無必然聯(lián)系酵使?coredata是一個關(guān)系型數(shù)據(jù)庫嗎? 答:iOS 中可以有四種持久化數(shù)據(jù)的方式:屬性列表(plist)焙糟、對象歸檔口渔、 SQLite3 和 Core Data; core data 可以使你以圖形界面的方式快速的定義 app 的數(shù)據(jù)模型酬荞,同時(shí)在你的代碼中容易獲取到它搓劫。 coredata 提供了基礎(chǔ)結(jié)構(gòu)去處理常用的功能瞧哟,例如保存混巧,恢復(fù),撤銷和重做勤揩,允許你在 app 中繼續(xù)創(chuàng)建新的任務(wù)咧党。在使用 core data 的時(shí)候,你不用安裝額外的數(shù)據(jù)庫系統(tǒng)陨亡,因?yàn)?core data 使用內(nèi)置的 sqlite 數(shù)據(jù)庫傍衡。 core data 將你 app 的模型層放入到一組定義在內(nèi)存中的數(shù)據(jù)對象。 coredata 會追蹤這些對象的改變负蠕,同時(shí)可以根據(jù)需要做相反的改變蛙埂,例如用戶執(zhí)行撤銷命令。當(dāng) core data 在對你 app 數(shù)據(jù)的改變進(jìn)行保存的時(shí)候遮糖, core data 會把這些數(shù)據(jù)歸檔绣的,并永久性保存。 mac os x 中sqlite 庫,它是一個輕量級功能強(qiáng)大的關(guān)系數(shù)據(jù)引擎屡江,也很容易嵌入到應(yīng)用程序芭概。可以在多個平臺使用惩嘉, sqlite 是一個輕量級的嵌入式 sql 數(shù)據(jù)庫編程罢洲。與 core data 框架不同的是, sqlite 是使用程序式的文黎, sql 的主要的 API 來直接操作數(shù)據(jù)表惹苗。 Core Data 不是一個關(guān)系型數(shù)據(jù)庫,也不是關(guān)系型數(shù)據(jù)庫管理系統(tǒng) (RDBMS) 臊诊。雖然 Core Dta 支持SQLite 作為一種存儲類型鸽粉,但它不能使用任意的 SQLite 數(shù)據(jù)庫。 Core Data 在使用的過程種自己創(chuàng)建這個數(shù)據(jù)庫抓艳。 Core Data 支持對一触机、對多的關(guān)系。 116. tableView 的重用機(jī)制玷或? 答:UITableView 通過重用單元格來達(dá)到節(jié)省內(nèi)存的目的: 通過為每個單元格指定一個重用標(biāo)識符(reuseIdentifier),即指定了單元格的種類,以及當(dāng)單元格滾出屏幕時(shí),允許恢復(fù)單元格以便重用.對于不同種類的單元格使用不同的ID,對于簡單的表格,一個標(biāo)識符就夠了.作者:Coder_凡鏈接:http://www.reibang.com/p/b0c98dbf0639來源:簡書簡書著作權(quán)歸作者所有儡首,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。