1竖螃、Object-c有多繼承嗎?沒有的話用什么代替逗余?
Objective-c只支持單繼承特咆,如果要實現(xiàn)多繼承的話,可以通過類別和協(xié)議的方式來實現(xiàn)录粱,cocoa中所有的類都是NSObject 的子類坚弱,多繼承在這里是用protocol委托代理來實現(xiàn)的蜀备。
2、定義屬性時荒叶,什么情況下使用readwrite碾阁,readonly,assign些楣,retain脂凶,copy,nonatomic愁茁?
1> readwrite:同時生成get方法和set方法的聲明和實現(xiàn)
2> readonly:只生成get方法的聲明和實現(xiàn)
3> assign:set方法的實現(xiàn)是直接賦值蚕钦,用于基本數(shù)據(jù)類型
4> retain:set方法的實現(xiàn)是release舊值,retain新值鹅很,用于OC對象類型
5> copy:set方法的實現(xiàn)是release舊值嘶居,copy新值,用于NSString促煮、block等類型
6> nonatomic:非原子性邮屁,set方法的實現(xiàn)不加鎖(比atomic性能高)
3、category和extension的區(qū)別?
相同點:都可以為一個類添加方法
不同點:
Categories在@implementation中不提供實現(xiàn)菠齿,編譯器不會報錯佑吝,運行調(diào)用時出錯;Extensions在@implementation中不提供實現(xiàn)绳匀,編譯器警告芋忿;
Category只能用于添加方法,不能用于添加成員變量疾棵。extension中聲明的方法和添加的成員變量是私有的戈钢,只有主implement能調(diào)用,外部的類無法調(diào)用是尔;
Category 增加的方法如果與類的方法同名殉了,會覆蓋原類的方法,因為Category的優(yōu)先級更高嗜历!Extensions則會沖突報錯宣渗。
4、MVC是什么梨州,有何特性痕囱,在iOS中是如何體現(xiàn)的?
MVC是Model-View-Controller,就是模型-視圖-控制器暴匠。MVC把軟件系統(tǒng)分為三個部分:Model鞍恢,View,Controller。在cocoa中帮掉,你的程序中的每一個object(對象)都將明顯地僅屬于這三部分中的一個弦悉,而完全不屬于另外兩個。
5蟆炊、怎么實現(xiàn)一個單例類?
實現(xiàn)Foo類的一個單例
static Foo * foo;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
foo = [[Foo alloc]init];
});
6稽莉、 delegate和notification的區(qū)別,分別在什么情況下使用?
delegate(委托模式):1對1的反向消息通知功能涩搓。
Notification(通知模式):只想要把消息發(fā)送出去污秆,告知某些狀態(tài)的變化。但是并不關(guān)心誰想要知道這個昧甘。
7良拼、iOS怎么實現(xiàn)數(shù)據(jù)的持久化,簡要介紹?
PList充边、userDefaults庸推、歸檔、數(shù)據(jù)庫浇冰、coreData
iOS中可以有四種持久化數(shù)據(jù)的方式: 屬性列表贬媒、對象歸檔、SQLite3和Core Data湖饱;core data可以使你以圖形界面的方式快速的定義app的數(shù)據(jù)模型掖蛤,同時在你的代碼中容易獲取到它杀捻。core data提供了基礎(chǔ)結(jié)構(gòu)去處理常用的功能井厌,例如保存,恢復致讥,撤銷和重做仅仆,允許你在app中繼續(xù)創(chuàng)建新的任務(wù)。在使用core data的時候垢袱,你不用安裝額外的數(shù)據(jù)庫系統(tǒng)墓拜,因為core data使用內(nèi)置的sqlite數(shù)據(jù)庫。core data將你app的模型層放入到一組定義在內(nèi)存中的數(shù)據(jù)對象请契。core data會追蹤這些對象的改變咳榜,同時可以根據(jù)需要做相反的改變,例如用戶執(zhí)行撤銷命令爽锥。當core data在對你app數(shù)據(jù)的改變進行保存的時候涌韩,core data會把這些數(shù)據(jù)歸檔,并永久性保存氯夷。
mac os x中sqlite庫臣樱,它是一個輕量級功能強大的關(guān)系數(shù)據(jù)引擎,也很容易嵌入到應用程序」秃粒可以在多個平臺使用玄捕,sqlite是一個輕量級的嵌入式sql數(shù)據(jù)庫編程。與core data框架不同的是棚放,sqlite是使用程序式的枚粘,sql的主要的API來直接操作數(shù)據(jù)表。
coredata是蘋果提供一套數(shù)據(jù)保存框架飘蚯,其基于SQlite
8赌结、frame和bounds的區(qū)別?
frame
是指視圖在其父視圖坐標系統(tǒng)中的位置和大小孝冒。它的坐標是相對于父視圖的左上角原點的柬姚。frame
屬性包含了視圖的origin
(x和y坐標)和size
(寬度和高度)。bounds
是指視圖在其自身坐標系統(tǒng)中的位置和大小庄涡。它的坐標是相對于視圖自身的左上角原點的量承。bounds
屬性只包含了視圖的origin
為(0, 0)和size
(寬度和高度)。
總結(jié)來說穴店,frame
描述了視圖在父視圖坐標系統(tǒng)中的位置和大小撕捍,而bounds
描述了視圖在自身坐標系統(tǒng)中的位置和大小。因此泣洞,當視圖發(fā)生旋轉(zhuǎn)或縮放時忧风,frame
會隨之改變,而bounds
保持不變球凰。
需要注意的是狮腿,frame
和bounds
屬性都是CGRect
類型的結(jié)構(gòu)體。CGRect
結(jié)構(gòu)體包含origin
和size
屬性呕诉,分別表示視圖的起點和大小缘厢。
9、Tableview的重用機制?
復用隊列的元素增加:只有在cell被滑動出界面的時候甩挫,此cell才會被加入到復用隊列中贴硫。每次在創(chuàng)建cell的時候,程序會首先通過調(diào)用dequeueReusableCellWithIdentifier:cellType方法伊者,到復用隊列中去尋找標示符為“cellType”的cell英遭,如果找不到,返回nil亦渗,然后程序去通過調(diào)用[[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:cellType] autorelease]來創(chuàng)建標示符為“cellType”的cell挖诸。
10、列舉ios中常見的幾種多線程的實現(xiàn)央碟,并談?wù)劧嗑€程安全的解決方法税灌,一般什么地方用到多線程?
線程有三種:NSThread均函、GCD、NSOperation
解決多線程安全問題的方法
方法一:互斥鎖(同步鎖)
@synchronized(鎖對象) {
// 需要鎖定的代碼
}
判斷的時候鎖對象要存在菱涤,如果代碼中只有一個地方需要加鎖苞也,大多都使用self作為鎖對象,這樣可以避免單獨再創(chuàng)建一個鎖對象粘秆。
加了互斥做的代碼如迟,當新線程訪問時,如果發(fā)現(xiàn)其他線程正在執(zhí)行鎖定的代碼攻走,新線程就會進入休眠殷勘。
方法二:自旋鎖
加了自旋鎖,當新線程訪問代碼時昔搂,如果發(fā)現(xiàn)有其他線程正在鎖定代碼玲销,新線程會用死循環(huán)的方式,一直等待鎖定的代碼執(zhí)行完成摘符。相當于不停嘗試執(zhí)行代碼贤斜,比較消耗性能。
屬性修飾atomic本身就有一把自旋鎖逛裤。
下面說一下屬性修飾nonatomic 和 atomic
nonatomic 非原子屬性,同一時間可以有很多線程讀和寫
atomic 原子屬性(線程安全)瘩绒,保證同一時間只有一個線程能夠?qū)懭?但是同一個時間多個線程都可以取值),atomic 本身就有一把鎖(自旋鎖)
atomic:線程安全带族,需要消耗大量的資源
nonatomic:非線程安全锁荔,不過效率更高,一般使用nonatomic
參考文章
11蝙砌、 Storyboard和xib的區(qū)別?
共同點:
都是用來描述軟件界面
都用Interface Builder工具來編輯
本質(zhì)都是轉(zhuǎn)換成代碼去創(chuàng)建控件
不同點:
Xib是輕量級的阳堕,用來描述局部 UI界面
StoryBoard是重量級的,用來描述整個軟件的多個界面拍霜,并且能展示多個界面之間的跳轉(zhuǎn)關(guān)系嘱丢。
參考地址
12薪介、UIView的圓角屬性設(shè)置方法?
(1)不好的解決方案:
使用下面的方式會強制Core Animation提前渲染屏幕的離屏繪制, 而離屏繪制就會給性能帶來負面影響祠饺,會有卡頓的現(xiàn)象出現(xiàn)。
self.view.layer.cornerRadius = 5.0f;
self.view.layer.masksToBounds = YES;
(2)正確的解決方案:使用繪圖技術(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;
}
(3)還有一種方案:
使用了貝塞爾曲線"切割"個這個圖片, 給UIImageView 添加了的圓角汁政,其實也是通過繪圖技術(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];
13、解釋一下iOS應用沙盒機制
每個應用程序都有自己的存儲空間记劈。
每個應用程序都不可以翻過自己的圍墻去訪問別的存儲空間的內(nèi)容勺鸦。(已經(jīng)越獄的除外)
在訪問別人沙盒內(nèi)的數(shù)據(jù)時需要訪問權(quán)限。
參考
14目木、談?wù)凨VO和KVC
KVC
kvc:鍵 – 值編碼换途,是一種間接訪問對象的屬性,使用字符串來標示屬性。
很多情況下可以簡化程序代碼军拟。apple文檔其實給了一個很好的例子剃执。
結(jié)論:
1、先去類中查找 該變量使用實現(xiàn)了setter和getter方法聲明與實現(xiàn)部分 如果具有就直接調(diào)用setter和getter方法
2懈息、如果不具有 就去類中查找是否具有以 該變量命名 的成員變量肾档,如果具有直接賦值。
3辫继、如果都不具有 就去類中查找是否具有以下劃線開頭以該變量命名的成員變量 如果具有直接賦值 如果在不具有直接崩潰
KVO
kvo:鍵值觀察機制怒见,他提供了觀察某一屬性變化的方法,極大的簡化了代碼姑宽。
KVO用來觀察 成員變量 變化前和變化后的值
被觀察的成員變量只要一發(fā)生改變就會觸發(fā)相應的方法
該方法是系統(tǒng)自帶的方法 無需手動調(diào)用 編譯器會自動調(diào)用
[注意]在MRC編碼的情況下 必須在dealloc方法中釋放觀察值
KVO底層實現(xiàn)原理
KVO是基于runtime機制實現(xiàn)的
當某個類的屬性對象第一次被觀察時遣耍,系統(tǒng)就會在運行期動態(tài)地創(chuàng)建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter 方法炮车。派生類在被重寫的setter方法內(nèi)實現(xiàn)真正的通知機制
如果原類為Person配阵,那么生成的派生類名為NSKVONotifying_Person
每個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察示血,那么系統(tǒng)會偷偷將isa指針指向動態(tài)生成的派生類棋傍,從而在給被監(jiān)控屬性賦值時執(zhí)行的是派生類的setter方法
鍵值觀察通知依賴于NSObject 的兩個方法: willChangeValueForKey: 和 didChangevlueForKey:;在一個被觀察屬性發(fā)生改變之前难审, willChangeValueForKey:一定會被調(diào)用瘫拣,這就 會記錄舊的值。而當改變發(fā)生后告喊,didChangeValueForKey:會被調(diào)用麸拄,繼而 observeValueForKey:ofObject:change:context: 也會被調(diào)用。
補充:KVO的這套實現(xiàn)機制中蘋果還偷偷重寫了class方法黔姜,讓我們誤認為還是使用的當前類拢切,從而達到隱藏生成的派生類
15、網(wǎng)絡(luò)數(shù)據(jù)獲取后的幾種格式秆吵,它們的區(qū)別淮椰, iOS中是如何解析這幾種格式的數(shù)據(jù)?
JSON解析、XML解析
JSON解析
第三方框架 JSONKit\SBJSON\TouchJSON
蘋果原生(NSJSONSerialization)
XML解析
使用NSXMLParser解析XML
使用GDataParser解析XML
參考
16纳寂、現(xiàn)在有一個需求是存儲一個學校的所有學生,請創(chuàng)建相關(guān)表格來存儲,要可以區(qū)分出年級主穗、班級和學生信息。如上題所示, (1)請寫出SQL查詢所有學生的年級,班級名稱毙芜;(2)請寫出SQL查詢每一個班級的學生人數(shù)
17忽媒、請寫出有哪些排序算法,并寫出一個排序腋粥。
快速排序晦雨、冒泡排序架曹、選擇排序
冒泡排序
/**
OC版冒泡排序,必須傳入可變數(shù)組,數(shù)組包含數(shù)字元素
@param mArray 可變數(shù)組
@return 排好序的數(shù)組
*/
-(NSMutableArray *)maopaoSortWithMarray:(NSMutableArray *)mArray{
//外層循環(huán)
for (int i = 0; i < mArray.count; i ++) {
//內(nèi)層循環(huán)
for (int j = 0; j <mArray.count - i; j++) {
//比較大小
//升序
if ([mArray[j] intValue] > [mArray[j +1] intValue]) {
//交換
[mArray exchangeObjectAtIndex:j withObjectAtIndex:j+1];
}
// //降序
// if ([mArray[j] intValue] < [mArray[j +1] intValue]) {
// //交換
// [mArray exchangeObjectAtIndex:j withObjectAtIndex:j+1];
// }
}
}
return mArray;
/*
用法:
//傳入數(shù)組
NSMutableArray * mArray = [NSMutableArray arrayWithArray:@[@6,@4,@9,@5,@8,@0,@30]];
//得到數(shù)組:
NSArray * resultsArray = [NSArray maopaoSortWithMarray:mArray];
NSLog(@"冒泡排序好的數(shù)組:%@",resultsArray);
*/
}