![iOS程序員面試分類模擬22_第1頁](http://file4.renrendoc.com/view3/M00/37/2E/wKhkFmZah5-AfwqKAALuY7gDlhc848.jpg)
![iOS程序員面試分類模擬22_第2頁](http://file4.renrendoc.com/view3/M00/37/2E/wKhkFmZah5-AfwqKAALuY7gDlhc8482.jpg)
![iOS程序員面試分類模擬22_第3頁](http://file4.renrendoc.com/view3/M00/37/2E/wKhkFmZah5-AfwqKAALuY7gDlhc8483.jpg)
![iOS程序員面試分類模擬22_第4頁](http://file4.renrendoc.com/view3/M00/37/2E/wKhkFmZah5-AfwqKAALuY7gDlhc8484.jpg)
![iOS程序員面試分類模擬22_第5頁](http://file4.renrendoc.com/view3/M00/37/2E/wKhkFmZah5-AfwqKAALuY7gDlhc8485.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
iOS程序員面試分類模擬22簡答題1.
如何查看設(shè)備應(yīng)用的crash日志?正確答案:對于一般可重現(xiàn)的bug,可以通過再次運(yùn)行應(yīng)用找到問題所在。但是對于某些偶爾出現(xiàn)的錯(cuò)誤,尤其是內(nèi)存錯(cuò)誤就很難定位了(江南博哥),因?yàn)樵俅芜\(yùn)行可能錯(cuò)誤不會(huì)再次出現(xiàn),所以需要通過查看crash日志,來定位當(dāng)時(shí)發(fā)生錯(cuò)誤的位置。
crash日志可以分成兩種:一種是應(yīng)用發(fā)布AppStore后,用戶的crash日志會(huì)上傳,開發(fā)者可以在iTunesConnect上查看,但前提是用戶在手機(jī)設(shè)置中開啟了“診斷與用量”選項(xiàng),用戶同意分享應(yīng)用崩潰日志等信息給開發(fā)者(具體位置位于:設(shè)置→隱私→診斷與用量)。
另一種是開發(fā)者在開發(fā)測試時(shí)查看crash日志信息。查看測試過程中的日志也有多種途徑,例如運(yùn)行時(shí)可以連接Mac(模擬器或真機(jī)調(diào)試)在本地目錄中查看:~/Library/Logs/CrashReporter/MobileDevice/設(shè)備名稱/。日志文件擴(kuò)展名為.crash或.ips,如圖所示。
日志文件
還有主要是在Xcode中查看日志,位置位于Xcode中Window導(dǎo)航欄下的Devices選項(xiàng),打開會(huì)有模擬器和真機(jī)的設(shè)備列表。選中設(shè)備,在有日志的情況下會(huì)有ViewDeviceLogs選項(xiàng),如圖所示。
Xcode中查看日志
2.
什么是消息推送?和NotificatiOil有什么區(qū)別?正確答案:消息推送指在App關(guān)閉時(shí)(不在前臺運(yùn)行時(shí)),仍然向用戶發(fā)送App的內(nèi)部消息。消息推送通知和Objective-C中的Notification通知機(jī)制不同,推送的消息是給用戶看的,也就是可見的,而通知機(jī)制是Objective-C語言中對象間通信的一種機(jī)制,基于觀察者模式,目的是觸發(fā)內(nèi)部事件,減小類之間的耦合度,對用戶是不可見的。
推送消息的可見形式主要有以下幾種:
1)鎖屏界面的橫幅推送消息。
2)頂部通知欄的橫幅推送消息。
3)應(yīng)用圖標(biāo)上的代表消息數(shù)量的紅色數(shù)字。
4)菜單頁面彈出框提示。
5)播放聲音提示。
下圖所示是iPhone中QQ推送的設(shè)置界面。
QQ推送的設(shè)置界面
下圖所示為iPhone中消息推送的形式。
iPhone中消息推送的形式
iOS開發(fā)中有兩種類型的消息推送:本地消息推送(LocalNotification)和遠(yuǎn)程消息推送(RemoteNotification)。
1)本地消息推送:本地消息推送很簡單,不需要聯(lián)網(wǎng),不需要服務(wù)器,由客戶端應(yīng)用直接發(fā)出推送消息,一般通過定時(shí)器在指定的時(shí)間進(jìn)行消息推送。
2)遠(yuǎn)程消息推送:遠(yuǎn)程消息推送過程略為復(fù)雜,需要客戶端從蘋果公司的APNS(ApplePushNotificationSerwices)服務(wù)器注冊獲得當(dāng)前用戶的設(shè)備令牌并發(fā)送給應(yīng)用的服務(wù)器,然后應(yīng)用的服務(wù)器才可以通過APNS服務(wù)器間接地向客戶端發(fā)送推送消息,期間難免會(huì)有延遲。
遠(yuǎn)程消息推送的具體流程如圖所示,開發(fā)中要和服務(wù)器合作共同完成。
遠(yuǎn)程消息推送流程圖
①App客戶端向APNS服務(wù)器發(fā)送設(shè)備的UDID和BundleIdentifier。
②APNS服務(wù)器對傳過來的信息加密生成一個(gè)deviceToken,并返回給客戶端。
③客戶端將當(dāng)前用戶的deviceToken發(fā)送給自己應(yīng)用的服務(wù)器。
④自己應(yīng)用的服務(wù)器將得到的deviceToken保存,需要的時(shí)候利用deviceToken向APNS服務(wù)器發(fā)送推送消息。
⑤APNS服務(wù)器接收到自己應(yīng)用的服務(wù)器的推送消息時(shí),驗(yàn)證傳過來的deviceToken,如果一致,那么將消息推送到客戶端。
3.
如何在Category中增加屬性(關(guān)聯(lián)對象)?正確答案:在實(shí)際開發(fā)中,如果為Category添加一個(gè)屬性,那么系統(tǒng)將不會(huì)為這個(gè)屬性設(shè)置訪問器方法,也就是setter和getter方法。這時(shí)候可以使用runtime提供的關(guān)聯(lián)對象方法,動(dòng)態(tài)地為該屬性實(shí)現(xiàn)訪問器方法。
開發(fā)者可以將關(guān)聯(lián)對象想象成一個(gè)Objective-C對象,這個(gè)對象通過一個(gè)預(yù)先設(shè)置好的key連接到類的一個(gè)實(shí)例上。runtime提供了如下方法讓一個(gè)對象連接到其他對象。
voidobjc_setAssociatedObject(idobject,constvoid*key,
idvalue,objc_AssociationPolicypoliey)
參數(shù)object是將要被關(guān)聯(lián)的對象。參數(shù)key是一個(gè)void指針。參數(shù)value是關(guān)聯(lián)對象,它是id類型。參數(shù)policy是指定一個(gè)內(nèi)存管理策略來處理關(guān)聯(lián)對象。如果指定的策略O(shè)BJC_ASSOCIATION_ASSIGN,那么被關(guān)聯(lián)對象釋放時(shí),關(guān)聯(lián)對象不會(huì)被釋放,而如果指定的OBJC_ASSOCIATION_RETAIN或OBJC_ASSOCIATION_COPY,那么關(guān)聯(lián)對象就會(huì)被釋放。另外,還有OBJC_ASSOCIATION_RETAIN_NONATOMIC和OBJC_ASSOCIATIO_COPY_NONATOMIC兩種策略,當(dāng)需要在多個(gè)線程中處理訪問關(guān)聯(lián)對象的多線程代碼時(shí),就會(huì)變得非常有用。
除此之外,runtime還提供了移除關(guān)聯(lián)對象的方法:
voidobjc_removeAssociatedObjects(idobject)
可以使用這個(gè)方法移除所有和參數(shù)object關(guān)聯(lián)的對象,或者使用objc_setAssociatedObject函數(shù)將key指定的關(guān)聯(lián)對象設(shè)置為nil。
下面的示例代碼演示了如何為Person的Category添加一個(gè)屬性。
/*為Person類的Category添加address屬性*/
#import"Person.h"
@interfacePerson(Cate)
@property(nonatomic,strong)NSString*address;
@end
/*在.m文件中為address屬性實(shí)現(xiàn)訪問器方法*/
#import"Person+Cate.h"
#import<o(jì)bje/objc-runtime.h>
@implementationPerson(Cate)
-(id)address{
idvalue=objc_getAssociatedObject(se!f,"address");
returnvalue;
}
-(void)setAddress:(NSString*)address{
objc_setAssociatedObject(self,"address",address,OBJC_ASSOCIATION_RETAIN);
}
@end
/*在控制器中打印屬性值*/
Person*aperson=[[Personalloc]init];
aperson.address=@"China";
NSLog(@"address=%@",aperson.address);
程序的打印結(jié)果如下:
2016-11-0319:17:40.94901[2756:152639]aaddress=China
結(jié)果說明已經(jīng)成功地在Category中為類添加了一個(gè)新的屬性,并且能夠正常地使用這個(gè)屬性。事實(shí)上,關(guān)聯(lián)對象是使用哈希表實(shí)現(xiàn)的,將一個(gè)類映射到一張哈希表上,然后根據(jù)key找到關(guān)聯(lián)對象,所以嚴(yán)格來說,關(guān)聯(lián)對象和被關(guān)聯(lián)對象沒有任何關(guān)系,它不是存儲在對象的內(nèi)部。
4.
Objective-C中的可變和不可變類型是什么?正確答案:Objective-C中的mutable和immutable類型對應(yīng)于動(dòng)態(tài)空間分配和靜態(tài)空間分配。最常見的例子是數(shù)組和字典。例如NSArray和NSMutableArray,前者為靜態(tài)數(shù)組(不可變數(shù)組),初始化后長度固定,不可以再動(dòng)態(tài)添加新元素改變數(shù)組長度;后者為動(dòng)態(tài)數(shù)組(可變數(shù)組),可以使用addObject方法動(dòng)態(tài)添加或者使用removeObject方法刪除元素,動(dòng)態(tài)申請新的空間或釋放不需要的空間,伸縮數(shù)組長度。
/*不可變數(shù)組,初始化后不可添加或刪除數(shù)組元素*/
NSArray*array=[[NSArrayalloc]initWithObjects:@1,@2,@3,nil];
/*可變數(shù)組,初始化后可以繼續(xù)添加或刪除數(shù)組元素*/
NSMutableArray*mulArray=[[NSMutableArrayalloc]initWithObjects:@4,@5,@6,nil];
[mulArrayaddObject:@7];
[mulArrayremoveObjectAtIndex:0];
[mulArrayremoveObject:@5];
5.
如何使用NSUserDefault偏好設(shè)置保存數(shù)據(jù)?正確答案:NSUserDefault是iOS系統(tǒng)提供的一個(gè)單例類,通過它可以將用戶的偏好設(shè)置保存到應(yīng)用包的plist文件中,同時(shí)也能讀取保存的數(shù)據(jù)。通過類方法+standardUserDefaults可以獲得NSUserDefault單例。
NSUserDefaults*userDefault=[NSUserDefaultsstandardUserDefaults];
NSUserDefault單例以key-value的形式存儲數(shù)據(jù),key是名稱,value是相應(yīng)的數(shù)據(jù)。使用-setObject:forKey:和-objectForKey:來存/取數(shù)據(jù)。下面的示例演示了一般的存取操作。
-(void)userDefaultSave{
NSUserDefaults*defaults=[NSUserDefaultsstandardUserDefaults];
[defaultssetObject:@"jack"forKey:@"name"];
[defaultssetInteger:10forKey:@"age"];
/*下面的代碼可以省略,這里只是作為演示*/
if([defaultssynchronize]){
NSLog(@"保存成功");
}
}
-(void)userDefaultGet{
NSUserDefaults*defaults=[NSUserDefaultsstandardUserDefaults];
NSString*name=[defaultsobjectForKey:@"name"];
NSIntegerage=[defaultsintegerForKey:@"age"];
NSLog(@"name=%@,age=%zd",name,age);
}
需要注意的是,默認(rèn)情況下NSUserDefaults只能存儲基本對象類型(如NSData、NSString等類型)和基本數(shù)據(jù)類型,直接保存自定義對象將會(huì)拋出類似如下的異常。
Terminatingappduetouncaughtexception'NSInvalidArgumentException',reason:'Attempttoinsertnon-propertylistobject<UIImage:0x608000092d40>,{400,250}forkeyimg'
此時(shí)需要自定義類遵守NSCoding協(xié)議并實(shí)現(xiàn)協(xié)議方法進(jìn)行編碼與反編碼,再通過NSKevedUnarchiver類將自定義對象轉(zhuǎn)為NSData對象,之后才能使用NSUserDefaults進(jìn)行存儲。簡單來說,對于自定義類對象,必須要通過一些方式將其轉(zhuǎn)化為基本類型,即遵循NSCoding協(xié)議。下面的示例展示了如何保存UIImage對象。
-(void)userDefaultSaveImage{
UIImage*img=[UIImageimageNamed:@"1"];
NSUserDefaults*defaults=[NSUserDefaultsstandardUserDefaults];
/*直接保存將產(chǎn)生錯(cuò)誤:[defaultssetObject:imgforKey:@"img"];*/
/*轉(zhuǎn)為NSData對象*/
NSData*data=UIImageJPEGRepresentation(img,1);
[defaultssetObject:dataforKey:@"img"];
}
-(void)userDefaultGetImage{
NSUserDefaults*defaults=[NSUserDefaultsstandardUserDefaults];
/*轉(zhuǎn)為NSData對象*/
NSData*data=[defaultsobjectForKey:@"img"];
/*轉(zhuǎn)為UIImage對象*/
UIImage*img=[UIImageimageWithData:data];
self.view.layer.contents=(id)img.CGImage;
}
6.
iOS中是如何使用自定義字體的?正確答案:字體是軟件開發(fā)中個(gè)性化的一個(gè)重要元素,系統(tǒng)自帶了很多豐富的字體,但有時(shí)候并不能滿足個(gè)性化的需求,這時(shí)候可以向工程中添加自定義的系統(tǒng)字體,然后就可以像使用系統(tǒng)字體一樣使用。字體文件最常用的為ttf等格式。
導(dǎo)入自定義字體過程很簡單:添加資源包到工程→在info.plist文件中注冊字體→在工程BundleResource中復(fù)制字體資源包→代碼檢測查詢加入的字體并使用。
1.添加資源包
addFile添加字體資源包或者直接將字體包拖到工程資源文件夾下(見圖1)。
圖1
字體文件拖入工程目錄
2.info.plist文件中注冊字體,添加字體資源包
在工程的info.plist屬性列表中添加Fontsprovidedbyapplication數(shù)組屬性,并在其下添加要加入的自定義字體項(xiàng)(見圖2和圖3)。注意,這里在plist文件中寫的是文件的全稱,包括文件擴(kuò)展名,文件的名字是可以隨便改的,但建議用本來的字體族名,例如這里是:KristenITC,字體族名是不會(huì)變的,之后具體代碼中使用的時(shí)候是用的字體族名而不是自定義的文件名。本來的字體族名可以右鍵查看字體文件的詳細(xì)信息,里面的全稱是本來的字體族名,而名稱是自定義的。字體注冊后將資源包復(fù)制到BundleResource即可(見圖3)。
圖2
配置info.plist
圖3
添加注冊自定義字體項(xiàng)
圖4
字體包復(fù)制到BundleResource
3.檢測是否成功加入字體
在具體使用之前,可以先通過UIFont類提供的方法打印出系統(tǒng)所有的字體列表,并找到剛添加的字體驗(yàn)證是否添加成功,還可以具體看到資源包有哪些具體的字體樣式,如該字體族的斜體、粗體、粗斜體等。打印字體族列表的代碼如下:
/*檢查自定義字體族是否成功加入*/
/*取出系統(tǒng)安裝了的所有字體族名*/
NSArray*familyNames=[UIFont=familyNames];
NSLog(@"系統(tǒng)所有字體族名:%@",familyNames);
/*打印字體族的所有子字體名(每種字體族可能對應(yīng)多個(gè)子樣式字體,例如每種字體族可能有粗體、斜體、粗斜體等等樣式)*/
for(NSString*familyNameinfamilyNames){
/*字體族的所有子字體名*/
NSArray*detailedNames=[UIFontfontNamesForFamilyName:familyName];
NSLog(@"\n字體族%@的所有了字體名:%@",familyName,detailedNames);
}
這里可以從字體組列表中找到剛添加的字體族KristenlTC,結(jié)果如圖5所示。
圖5
已有字體列表
還可以看到字體族KristenITC下的具體字體樣式,這里只有一種也是默認(rèn)的一種:KristenlTC-Regular(見圖6)。
圖6
字體名
4.使用字體
確定字體加入系統(tǒng)之后就可以像自帶的系統(tǒng)字體一樣直接使用了(字體效果如圖7所示)。
/*設(shè)置label的字體和大小f這里直接使用字體族名也是可以的,有默認(rèn)的子字體樣式,也可以根據(jù)需求具體到子字體例如這里的:KristenITC-Regular)*/
[_labelsetFont:[UIFontfontWithName:@"KristenITC"size:35.0]];
圖7
字體效果
7.
什么是謂詞?正確答案:謂詞(NSPredicate)是Objective-C中針對數(shù)據(jù)集合的一種邏輯篩選條件,它類似于數(shù)據(jù)庫中SQL語句對數(shù)據(jù)篩選的限制約束條件。Objective-C中的謂詞經(jīng)常用來從數(shù)組(Array)、集合(Set)等數(shù)據(jù)集合中篩選數(shù)據(jù)元素,謂詞約束條件封裝在NSPredicate對象中,可通過類函數(shù)predicateWithFormat和邏輯約束語句進(jìn)行初始化。
這里以用謂詞從對象數(shù)組篩選對象為例展示謂詞的基本使用方法,謂詞對象使用基本的邏輯約束格式化字符串來初始化。假設(shè)有一個(gè)簡單的表(見表)結(jié)構(gòu)有name和age兩個(gè)字段:一個(gè)簡單的表nameageAmy9Lily10Sam12Eric18
謂詞篩選用法的示例代碼如下:
/*其中,Person是一個(gè)簡單的數(shù)據(jù)模型,它有name和age兩個(gè)屬性*/
/*數(shù)據(jù)源*/
NSArray*objectArray=[[NSArrayalloc]initWithObjects:
[PersonpersonWithName:@"Amy"age:9],
[PersonpersonWithName:@"Lily"age:10],
[PersonpersonWithName:@"Sam"age:12],
[PersonpersonWithName:@"Eric"age:18],
nil];
/*謂詞邏輯約束對象*/
NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"age>10"];
/*篩選數(shù)據(jù)(結(jié)果為Sam,Eric)*/
NSArray*newArray=[objectArrayfilteredArrayUsingPredicate:predicate];
上面的邏輯約束格式化字符串@"age>10"指篩選對象中屬性age大于10的所有對象,格式化字符串可以被看作三部分:左手表達(dá)式、邏輯符號和右手表達(dá)式。其中,左手表達(dá)式是一個(gè)對象的屬性鍵值(鍵路徑);邏輯符號是一個(gè)基本的邏輯運(yùn)算符;右手表達(dá)式是約束范圍。
邏輯運(yùn)算符還有很多,它們與SQL語句中的語法基本相對應(yīng),除了最基本的邏輯運(yùn)算符:>、==、<=、&&等之外,還有邏輯詞IN、CONTAINS、like等。它們的使用情況如下:
/*1.IN:名字為Sam或者Eric的對象*/
NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"nameIN{'Sam','Eric'}"];
1*2.&&:年齡大于10,并且年齡小于20的對象(結(jié)果為Sam,Eric)*/
NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"age>10&&age<20"];
/*3.CONTAINS:名字里有小寫字母a的對象(結(jié)果為Sam)*/
NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"nameCONTAINS'a'"];
/*4.like:正則匹配,?表示一個(gè)個(gè)占位符,*表示任意匹配*/
/*名字第三個(gè)字母為m的對象(結(jié)果為Sam)*/
NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"namelike'??m'"];
/*名字里有小寫字母a的對象(結(jié)果為Sam)*/
NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"namelike'*a*'"];
8.
什么是“懶加載”?正確答案:“懶加載”(Lazyloading)也被叫作“延遲加載”,它的核心思想是把對象的實(shí)例化盡量延遲,直到真正用到的時(shí)候才將其實(shí)例化,這樣做的好處是可以減輕大量對象在實(shí)例化時(shí)對資源的消耗,而不是在程序初始化的時(shí)候就預(yù)先將對象實(shí)例化。另外,“懶加載”可以將對象的實(shí)例化代碼從初始化方法中獨(dú)立出來,從而提高代碼的可讀性,以便于代碼能夠更好地被組織。
最典型的一個(gè)應(yīng)用“懶加載”的例子是在對象的getter方法中實(shí)例化對象的時(shí)候。例如getter方法被重寫,使得在第一次調(diào)用getter方法時(shí)才實(shí)例化對象并將實(shí)例化的對象返回。判斷是否是第一次調(diào)用getter方法可以通過判斷對象是否為空來實(shí)現(xiàn)?!皯屑虞d”的getter方法的實(shí)現(xiàn)模板如下:
/*getter*/
-(NSObject*)object{
if(!_bject){
_object=[[NSObjectalloc]init];
}
return_object;
}
這種實(shí)現(xiàn)方法的缺點(diǎn)是使得getter方法產(chǎn)生副作用,也就是破壞了getter方法的純潔性。因?yàn)榘凑占s定和習(xí)慣,getter方法就是作為接口簡單地將需要的實(shí)例對象返回給外部,這里對getter方法的第一次調(diào)用添加了懶加載模式,在使用者不知情的情況下會(huì)有潛在的隱患。
9.
CGAffineTransform和CATransform3D分別有什么作用?正確答案:CGAffineTransform被稱為“仿射變換”,它被定義在CoreGraphics框架中,主要用于在二維平面對視圖進(jìn)行旋轉(zhuǎn)、縮放和平移。事實(shí)上,CGAffineTransform是一個(gè)可以和二維空間向量(如CGPoint)做乘法的3×2的矩陣。CGAffineTransform中“仿射”的意思是無論使用什么值的變換矩陣,圖層中平行的兩條線在變換之后仍然會(huì)保持平行。
CoreGraphics框架提供了一系列函數(shù)來創(chuàng)建CGAffineTransform實(shí)例,主要有以下幾種:
/*平移*/
CGAffineTransformMakeTranslation(CGFloattx,CGFloatty)
/*縮放*/
GAffineTransformMakeScale(CGFloatsx,CGFloatsy)
/*旋轉(zhuǎn)*/
CGAffineTransformMakeRotation(CGFloatangle)
UIView中的transform屬性或者CALayer中的affineTransform屬性都是CGAffineTransform類型,可以使用它們對視圖或者圖層進(jìn)行仿射變換。此外,CoreGraphics框架還提供了一些可以進(jìn)行混合變換的函數(shù),能夠在一個(gè)變化的基礎(chǔ)上做更深層次的變換,甚至可以將兩個(gè)已經(jīng)存在的變換矩陣進(jìn)行合并。如果要做多次變換的操作,那么這些函數(shù)就會(huì)非常有用。下面用例子來演示一個(gè)包含縮放、旋轉(zhuǎn)和移動(dòng)的變換,示例代碼如下:
-(void)viewDidLoad{
[superviewDidLoad];
_searchImageView=[[UIImageViewalloc]initWithFrame:CGRectMake(([UIScreenmainSereen].bounds.size:width-200)*0.5,([UIScreenmainScreen].bounds.size:height-200)*0.5,200,200)];
_searchImageView.image=[UIImageimageNamed:@"馬"];
[self.viewaddSubview:_searchImageView];
}
-(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event{
/*創(chuàng)建一個(gè)空的CGAffineTransform*/
CGAffineTransformtransform=CGAffineTransformIdentity;
/*縮放*/
transform=CGAffineTransformScale(transform,0.5,0.5);
/*旋轉(zhuǎn)*/
transform=CGAffineTransformRotate(transform,M_PI_4);
/*平移*/
transform=CGAffineTransformTranslate(transform,100,0);
_searchImageView.transform=transform;
}
CATransform3D是CoreAnimation結(jié)構(gòu)體。和CGAffineTransform一樣,它也是一個(gè)矩陣。CATransform3D主要用來做更復(fù)雜的關(guān)于CALayer的3D操作。CoreAnimation提供了一系列方法來創(chuàng)建和組合CATransform3D類型的矩陣,這些函數(shù)和CGAffineTransform類似,只是多了一個(gè)z參數(shù),并且旋轉(zhuǎn)函數(shù)除了angle之外還多出了x、y、z3個(gè)參數(shù),這些參數(shù)分別決定了每個(gè)坐標(biāo)軸方向上的旋轉(zhuǎn)。主要函數(shù)如下:
/*3D平移*/
CATransform3DMakeTranslation(CGFloattx,CGFloatty,CGFloattz)
/*3D旋轉(zhuǎn)*/
CATransform3DMakeRotation(CGFloatangle,CGFloatx,CGFloaty,CGFloatz)
/*3D縮放*/
CATransform3DMakeScale(CGFloatsx,CGFloatsy,CGFloatsz)
此外可以通過CATransform3D中的m34元素來控制3D變換的透視效果。m34元素主要用于按比例縮放X和Y的值來計(jì)算遠(yuǎn)離視角的距離。m34的默認(rèn)值是0,可以通過設(shè)置其為-1/d來應(yīng)用透視效果,d代表了視角和屏幕之間的距離,d的值越小,透視效果越強(qiáng),一般設(shè)置為500~1000。示例代碼如下:
-(void)viewDidLoad{
[superviewDidLoad];
_searchImageView=[UIImageViewalloc]initWithFrame:CGRectMake(([UIScreenmainScreen].bounds.size.width-200)*0.5,([UIScreenmainScreen].bounds.size.height-200)*0.5,200,200)];
_searchImageView.image=[UIImageimageNamed:@"馬"];
[self.viewaddSubview:_searchImageView];
/*創(chuàng)建一個(gè)空的CATransform3D*/
CATransform3Dtransform=CATransform3DIdentity;
/*設(shè)置m34元素,增強(qiáng)透視效果*/
transform.m34=-1.0/500.0;
/*3D旋轉(zhuǎn)變換*/
transform=CATransform3DRotate(transform,M_PI_4,0,1,0):
_searchImageView.layer:transform=transform;
}
10.
如何實(shí)現(xiàn)autorealeasepool?正確答案:autorealeasepool(自動(dòng)釋放池)其實(shí)并沒有其自身的結(jié)構(gòu),它是基于多個(gè)AutoreleasePoolPage(一個(gè)C++類)以雙向鏈表組合起來的結(jié)構(gòu),其基本操作都是簡單封裝了AutoreleasePoolPage的操作方法。例如,可以通過push操作添加對象,或者通過pop操作彈出對象,以及通過release操作釋放銷毀對象,對應(yīng)的3個(gè)封裝后的操作函數(shù)為:objc_autoreleasepoolPush、objc_autoreleasepoolPop和objc_autorelease。自動(dòng)釋放池將用完的對象集中起來,統(tǒng)一釋放,起到延遲釋放對象的作用。
自動(dòng)釋放池存儲于內(nèi)存中的棧上,釋放池之間遵循“先進(jìn)后出”原則。例如下面代碼所示的釋放池嵌套。
/*釋放池1*/
@autoreleasepool{
People*person1=[[[Personalloc]init]autoretease];
/*釋放池2*/
@autoreleasepool{
People*person2=[[[Personalloc]init]autorelease];
}
People*person3=[[[Personalloc]init]autorelease];
}
代碼中釋放池1和釋放池2在內(nèi)存中的結(jié)構(gòu)如圖所示,釋放池1先入棧,后出棧;釋放池2后入棧,先出棧。person2對象在釋放池2中,會(huì)被先釋放;person1和person3在釋放池1中,會(huì)后被釋放。
釋放池內(nèi)存結(jié)構(gòu)
自動(dòng)釋放池背后具體的實(shí)現(xiàn)機(jī)制比較復(fù)雜和巧妙,具體細(xì)節(jié)感興趣的讀者可以閱讀下面這篇博文中的討論:/2014/10/15/behind-autorelease/
11.
Git和SVN有什么異同?正確答案:Git和SVN都是用來對工程進(jìn)行版本控制的,它們可以監(jiān)控工程代碼或資源等文件的更改變化,保證正確的內(nèi)容提交或者撤銷恢復(fù)到之前的工程版本,有利于實(shí)現(xiàn)高效的團(tuán)隊(duì)合作。
Git和SVN的主要不同之處在于它們的架構(gòu)原理。簡單地說,Git是分布式的,而SVN是集中式的。當(dāng)使用Git時(shí),每個(gè)開發(fā)者要清楚本地倉庫和遠(yuǎn)程倉庫的概念,由于Git是分布式的,所以每個(gè)開發(fā)者建的本地倉庫都保存了整個(gè)工程的完整備份,而且與SVN不同的是,使用Git可以先在本地提交,在需要的時(shí)候再提交到遠(yuǎn)程倉庫從而推送給其他開發(fā)者看到,提交的過程即是同步的過程。也就是說,Git允許本地倉庫脫離遠(yuǎn)程服務(wù)器倉庫進(jìn)行本地工程的版本控制,而使用SVN每次提交時(shí),都要和中心服務(wù)器倉庫進(jìn)行同步。
由于兩者架構(gòu)的不同,所以Git和SVN中的分支(Branch)概念也是不同的。分支在SVN中是一個(gè)完整的目錄,包含所有的實(shí)際文件,和中心倉庫是保持同步的,如果某個(gè)團(tuán)隊(duì)成員創(chuàng)建新的分支,那么會(huì)同步到所有的成員版本中,所有人都會(huì)受影響,即牽一發(fā)而動(dòng)全身。而在Git下成員創(chuàng)建分支在合并前是不會(huì)影響任何人的,創(chuàng)建分支后可以在本地脫機(jī)進(jìn)行任何操作,測試無誤之后再提交合并到主分支,然后其他成員才能拉取看到。由此可見Git的優(yōu)勢是很明顯的。
另外,Git是把工程的內(nèi)容按照元數(shù)據(jù)的方式存儲,而SVN是把工程內(nèi)容按照文件的方式存儲。Git工程目錄往往比SVN目錄要大,因?yàn)镚it目錄中包含遠(yuǎn)程倉庫所有的數(shù)據(jù),如版本記錄、標(biāo)簽和分支等。
Git的整體結(jié)構(gòu)示意圖如圖所示。
Git的整體結(jié)構(gòu)示意圖
12.
如何理解MVVM設(shè)計(jì)模式?正確答案:隨著業(yè)務(wù)規(guī)模的不斷擴(kuò)大,業(yè)務(wù)邏輯也越來越復(fù)雜,這使得Controller中的任務(wù)越來越繁重,傳統(tǒng)的MVC架構(gòu)已經(jīng)很難滿足低耦合、高內(nèi)聚的設(shè)計(jì)要求。在這樣的背景下,MVVM(Model-View-ViewModel)誕生了。MVVM是由微軟公司提出的一種新的設(shè)計(jì)架構(gòu),它基于MVC架構(gòu),其特點(diǎn)是在View和Model之間多加了一層ViewModel來實(shí)現(xiàn)數(shù)據(jù)的綁定(data-binding),從而很好地解決了MVC中Controller過于臃腫的問題。下圖展示了MVVM設(shè)計(jì)模式的結(jié)構(gòu)。
MVVM設(shè)計(jì)模式結(jié)構(gòu)
MVVM中的ViewModel有以下幾個(gè)特點(diǎn):
1)ViewModel是有狀態(tài)的。ViewModel有自己的屬性,還會(huì)持有Model對象。
2)ViewModel與UI控件的無關(guān)性。ViewModel并不關(guān)心UI控件的相關(guān)邏輯,只關(guān)心自己的數(shù)據(jù)處理邏輯。
3)易于單元測試。以往的Controller過于復(fù)雜,無法進(jìn)行單元測試,而ViewModel測試起來簡單很多。
4)ViewModel可以抽離出來做轉(zhuǎn)換器給其他項(xiàng)目使用,從而最大程度上實(shí)現(xiàn)了代碼的復(fù)用。
MVVM設(shè)計(jì)模式的目的是幫助MVC設(shè)計(jì)模式中的(Sontroiler瘦身,將數(shù)據(jù)加工的任務(wù)從Controller中解放了出來,使得Controller只需要專注于業(yè)務(wù)分配的工作,讓MVVM中的ViewModel負(fù)責(zé)Model與View之間的通信,并完成通信間的額外操作,如數(shù)據(jù)轉(zhuǎn)換、字符拼接等操作。因此,ViewModel經(jīng)常作為轉(zhuǎn)換器使用,從而提高了代碼的復(fù)用性。ViewModel還能幫助Controller完成復(fù)雜的網(wǎng)絡(luò)請求邏輯,從而大大降低了Controller的復(fù)雜度。這里需要強(qiáng)調(diào)的是,ViewModel具有獨(dú)立性,它并不關(guān)心UI的業(yè)務(wù)邏輯,也不持有任何UI對象,只關(guān)心自己的數(shù)據(jù)處理邏輯是否正確。很多初學(xué)者不清楚ViewModel的用法,往往會(huì)錯(cuò)誤地將UI對象當(dāng)作ViewModel的屬性或者將UI對象的操作放入ViewModel的方法中,這些做法都是不正確的,沒有正真理解MVVM的含義。盡管MVVM帶來了很多好處,降低了代碼的耦合度和復(fù)雜度,但它往往要寫更多的代碼來實(shí)現(xiàn)一個(gè)功能,同時(shí)還增加了工程的規(guī)模,使得工程中的目錄比以前要稍多一些,不易查找文件。MVVM并不是iOS開發(fā)中的“銀彈”,沒有那種方法能完全解決軟件開發(fā)中的問題,但相對于MVC來說,MVVM無疑是一個(gè)更好的選擇。
13.
Objective-C中的NSInteger類型和C語言中的int類型有什么區(qū)別?正確答案:在Objective-C中,數(shù)據(jù)類型可以分為基本數(shù)據(jù)類型、對象類型和id類型?;緮?shù)據(jù)類型有int類型、float類型、double類型、char類型、布爾類型等。事實(shí)上,Objective-C中的NSInteger也是基本數(shù)據(jù)類型之一。在蘋果的API實(shí)現(xiàn)中,NSInterger是一個(gè)對int類型和long類型的封裝,它會(huì)識別當(dāng)前操作系統(tǒng)的位數(shù),自動(dòng)返回最大的類型。定義NSInteger類型的代碼如下:
#if__LP64__||(TARGET_OS_EMBEDDED&&!TARGET_OS_IPHONE)||TARGET_OS_WIN32||NS_BUILD_32_LIKE_64
typedeflongNSInteger;
typedefunsignedlongNSUInteger;
#else
typedefintNSInteger;
typedefunsignedintNSUInteger;
#endif
其中,#if、#else、typedef等都屬于預(yù)處理語言。上面這段代碼的意思是,當(dāng)系統(tǒng)是32位系統(tǒng)時(shí),NSInteger類型等價(jià)于int類型,即32位,但當(dāng)系統(tǒng)是64位時(shí),NSInteger類型等價(jià)于long類型,即64位。
可以看出,NSInteger是long或者int的別名,對應(yīng)的NSUInteger是unsignedlong或者unsignedint的別名。區(qū)別在于,NSInteger會(huì)根據(jù)系統(tǒng)是32位機(jī)還是64位機(jī)來動(dòng)態(tài)確定自身是整型還是長整型,從而可以很好地兼容兩種機(jī)器。因此,當(dāng)開發(fā)者不知道操作系統(tǒng)是什么類型的時(shí)候,通常應(yīng)該使用NSInteger,這也是蘋果公司推薦使用的基本數(shù)據(jù)類型之一。
另外,NSInteger是Objective-C基本數(shù)據(jù)類型,不是NSNumber的子類,也不是NSObject的子類。
14.
什么是SEL?正確答案:SEL又稱選擇器,表示的是一個(gè)方法的selector的指針。在很多方法名中都可以看到,例如UIControl.h中事件的監(jiān)聽方法:
-(void)addTarget:(nullableid)targetaction:(SEL)actionforControlEvents:(UIControlEvents)controlEvents;
其中,參數(shù)action就是SEL類型。SEL的定義如下:
typedefstructobjc_selector*SEL;
方法的selector用于表示運(yùn)行時(shí)方法的名字。Objective-C在編譯時(shí),會(huì)根據(jù)每個(gè)方法的名字、參數(shù)列表,生成一個(gè)唯一的整型標(biāo)識,這個(gè)標(biāo)識就是SEL。正因?yàn)槠渚哂形ㄒ恍?,所以在Objective-C的同一個(gè)類中,不能存在兩個(gè)同名的方法,即使參數(shù)類型不同也不行。
開發(fā)者可以在運(yùn)行時(shí)添加新的selector,也可以在運(yùn)行時(shí)獲取已存在的selector。可以通過下面3種方法來獲取SEL。
/*在運(yùn)行時(shí)注冊一個(gè)方法,返回一個(gè)SEL指針*/
SELsel_registerName(constchar*str)
/*編譯器提供的方法*/
@selector(selector)
/*通過字符串獲取SEL*/
NSSelectorFromString(NSString*aSelectorName);
事實(shí)上,工程中所有的SEL會(huì)組成一個(gè)Set集合,Set的特點(diǎn)就是具有唯一性,因此SEL也是唯一的。如果想要查找某個(gè)方法,那么只需要找到這個(gè)方法所對應(yīng)的SEL就可以了,SEL實(shí)際上就是根據(jù)方法名Hash轉(zhuǎn)換的一個(gè)字符串。
15.
相對于objective-C而言,Swift有什么新特性?正確答案:Swift是一門新型語言,它借鑒了Haskell、Ruby、Python、C#等語言特性,看上去偏腳本化。Swift仍然支持已有的Cocoa和CocoaTouch框架。
Swift的主要新特性如下:
1)安全:有嚴(yán)格的類型檢查。
2)強(qiáng)大:有高度優(yōu)化的LLVM編譯器。
3)新型:Swift借鑒多種語言特性,表達(dá)更簡單精確。
Swift與Objective-C和C/C++的基本對比見表。C/C++、objective-C和Swift三者基本對比
C/C++Objective-CSwift庫引入#include<stdio.h>#import<Foundation/Foundation.h>importFoundation頭文件#include“Person.h”#import“Person.h”無常量定義#defineSPEED1.0#defineSPEED1.0letSPEED=1.0成員變量聲明intage;intage;varage:Int類方法聲明staticvoidspeak();+(void)speak();classfuncspeak(){...}實(shí)例方法聲明intspeak();-(int)speak();funcspeak(){...}動(dòng)態(tài)內(nèi)存申請Person*person=malloc(sizeof(Person));Person*person=newPerson;Person*person=[Personalloc];Varperson=Person()類方法調(diào)用Person::speak();[Personspeak];Person.speak()實(shí)例方法調(diào)用Person->speak();[personspeak]Person.speak()字符串“String”@“String”“String”
1.從基本的ViewController代碼窺探Objective-C和Swift的區(qū)別
(1)Swift
/*ViewController.swift*|
importUIKit
classViewController:UIViewController{
@IBOutletweakvarlabel1:UILabel!
@IBActionfuncbutton1(sender:AnyObject){
label1.text="HelloiOS!!!"
}
overridefuncviewDidLoad(){
super.viewDidLoad()
//Doanyadditionalsetupafterloadingtheview,typicallyfromanib.
}
overridefuncdidReceiveMemoryWaming(){
super.didReceiveMemoryWarning()
//Disposeofanyresourcesthatcanberecreated.
}
(2)Objective-C
/*ViewController.h*/
#import<UIKit/UIKit.h>
@interfaceViewController:UIViewController
@property(weak,nonatomic)IBOutletUILabel*labell;
-(IBAction)buttonl:(id)sender;
@end
/*ViewController.m*/
#import"ViewController.h"
@interfaceViewController()
@end
@implementationViewController
@synthesizelabel1;
-(void)viewDidLoad{
[superviewDidLoad];
//Doanyadditionalsetupafterloadingtheview,typicallyfromanib.
}
-(void)didReceiveMemoryWaming{
[superdidReceiveMemoryWarning];
//Disposeofanyresourcesthatcanberecreated.
}
-(IBAction)button1:(id)sender{
label1.text=@"HelloiOS!!!";
}
@end
2.SwiR類的定義
整個(gè)類文件都定義在一個(gè)Swift文件內(nèi):
importFoundation
classBall{
/*變量*/
varcenterX:Float
varcenterY:Float
varradius:Float
/*初始化方法*/
init(centerX:Float,centerY:Float,radius:Float){
selfcenterX=centerX
self.centerY=centerY
self.radius=radius
}
/*實(shí)例方法*/
funcmove(moveX:Float,_moveY:Float){
self.centerX+=moveX
self.centerY+=moveY
}
/*類方法*/
classfuncaClassMethod(){
print("Iamaclassmethod")
}
}
...
/*創(chuàng)建對象*/
varball1=Ball(centerX:7.0,centerY:5.0,radius:6.0)
/*方法調(diào)用*/
ball1.move(moveX:1.0,1.0)
Ball.aClassMethod0
3.Objective-C和Swift語言中流程控制語句的比較
(1)Objective-C
/*條件判斷*/
if(a<b){
//Dosomethinghere
}else{
//Doanotherthinghere
}
/*for循環(huán)*/
for(inti=0;i<10;i++){
//Dosomethinghere
}
/*while循環(huán)*/
while(count<10){
//Dosomethinghere
}
/*do-while循環(huán)*/
do{
//Dosomcthinghere
}while(count<10);
(2)Swift
/*條件判斷*/
ifa<b{
//Dosomethinghere
}else{
//Doanotherthinghere
}
/*for循環(huán)*/
forinti=0;i<10;i++{
//Dosomethinghere
}
/*while循環(huán)*/
whilecount<10{
//Dosomethinghere
}
/*repeat-while循環(huán)*/
repeat{
//Dosomethinghere
}whilecount<10
4.Objective-C和Swift語言中String字符串的對比
(1)Objective-C
NSString*Str=@"string";
NSString*formatStr=[NSStringstringWithFormat:@"%@andfloat%f",Str,3.1415"];
(2)Swift
/*可變字符串*/
varStr="string"
varStr:String="string"
varStr=String("string")
/*不可變字符串*/
letStr="string"
letStr:String="string"
letStr=String("string")
5.Objective-C和Swift語言中Array和MultableArray的對比
(1)Objective-C
/*靜態(tài)數(shù)組*/
NSArray*array=[[NSArrayalloc]initWithObjects:ball1,ball2,nil];
array[0].radius=10;
/*可變數(shù)組*/
NSMutableArray*mArray=[[NSMutableArrayalloc]initWithCapacity:2];
[mArrayaddObject:ball1];
[mArrayaddObject:ball2];
Ball*newball=[mArrayobjectAtIndex:1];
[mArrayremoveObjectAtIndex:1];
(2)Swift
/*靜態(tài)數(shù)組*/
letmyArray:Array<Ball>=[ball1,ball2]
letmyArray:[Ball]=[ball1,ball2]
letmyArray=[ball1,ball2]
myArray[0].radius=10
/*可變數(shù)組*/
vatmyArray:[Ball]=[]
myArray.append(ball1)
myArray.append(ball2)
varnewBall=myArray[1]
myArray.remove(at:0)
6.Objective-C和Swift語言中UIImageView的使用對比
(1)Objective-C
UIImageView*myImage=[[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"tiger.png"]];
[self.viewaddSubview:myImage];
myImage.center=CGPointM
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 旅游行業(yè)數(shù)字化轉(zhuǎn)型項(xiàng)目投資合同
- 婚前合伙購房協(xié)議書
- 綠色能源項(xiàng)目培訓(xùn)服務(wù)合同
- 醫(yī)療器械保修合同
- 電子產(chǎn)品維修免責(zé)聲明及協(xié)議
- 重大項(xiàng)目推進(jìn)致辭及啟動(dòng)儀式方案
- 電子支付服務(wù)運(yùn)營協(xié)議
- 房屋中介獨(dú)家委托協(xié)議
- 上海中介租房服務(wù)合同
- 中國國際大學(xué)生創(chuàng)新大賽與“挑戰(zhàn)杯”大學(xué)生創(chuàng)業(yè)計(jì)劃競賽(第十一章)大學(xué)生創(chuàng)新創(chuàng)業(yè)教程
- 《建筑基坑工程監(jiān)測技術(shù)標(biāo)準(zhǔn)》(50497-2019)
- CB/T 102-1996錫基合金軸瓦鑄造技術(shù)條件
- 羅森便利店QSC標(biāo)準(zhǔn)課件講義
- 售后服務(wù)的流程圖
- 讀《讀懂孩子》讀書心得體會(huì)
- 《勞動(dòng)合同法》普法宣傳資料
- 二年級下冊科學(xué)教案-2.3科技產(chǎn)品體驗(yàn)會(huì) 大象版
- 退役軍人優(yōu)待證申領(lǐng)表
- 勞務(wù)分包項(xiàng)目經(jīng)理崗位職責(zé)
- 幼兒繪本故事:奇怪的雨傘店
評論
0/150
提交評論