以下是我收集總結的 iOS技術點+面試題 分類;看看你都會了嗎?
我們提供的服務有:成都網站設計、成都網站建設、微信公眾號開發、網站優化、網站認證、天祝藏族自治ssl等。為千余家企事業單位解決了網站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的天祝藏族自治網站制作公司
重點總結-四大分類 :
iOS底層原理(必問) :iOS開發必備能力,也是大廠面試快速篩選人才方式之一。
常問例題 :
性能優化以及架構能力 :目前大廠對于這一塊,非常重視;
常問例題:
多線程、網絡能力: iOS中高級開發,都應該了解,并且熟悉的知識點;
常問例題 :
數據結構算法能力占比比較大: 通常一般大公司都會有一些筆試:雖然不在核心崗位對于數據結構算法要求不是非常嚴格,但是也會有一些常規的數據結構和算法的題
常問例題:
推薦閱讀:iOS熱門面試技術文集
總結一下藍牙開發相關的知識點和注意事項,做個筆記,也希望你們能少踩坑
(公司部分藍牙項目為混編項目,藍牙相關處理均采用了Objective-C,故本文????均采用OC,Swift處理相同)
藍牙4.0包含兩個藍牙標準,它是一個是 雙模 的標準,它包含 傳統藍牙部分(也稱經典藍牙) 和 低功耗藍牙部分(BLE) , 二者適用于不同的應用場景和應用條件。他們的特點如下
所以藍牙4.0是集成了傳統藍牙和低功耗藍牙兩個標準的,并不只是低功耗藍牙
藍牙4.0支持兩種部署方式: 雙模式 和 單模式 ,雙模同時支持經典藍牙和低功耗藍牙,而單模則只支持其中一種。
二者更多細節詳見: 傳統藍牙和低功耗藍牙的區別
iOS中藍牙相關功能都封裝進了 CoreBluetooth 類中,其中有幾個常見的參數和概念
具體API參考 CoreBluetooth藍牙開發
保存到數組中的設備可通過 UUID 來進行區分。從 iOS7之后蘋果不提供外設的mac地址,外設的唯一標識換成了由mac封裝加密后的UUID,需要注意的是不同的手機獲取同一個外設的UUID是不同的,所以在不同手機之間UUID不是唯一的,但在本機上可以作為唯一標識(特殊情況手機刷機后也會改變UUID)。
如何獲取Mac地址
一般使用場景是根據Mac地址區分某個外設
注意點:
寫入數據時可能會遇到需要分包發送的情況,我們可以通過下面的API或許當前特征支持的最大的單條寫入長度
maxLength 一般取決于藍牙模塊內部接收 緩沖區 的大小,很多硬件設備這個緩沖區的大小是 20 字節, 這個大小也和特征的寫入權限有關,像具有寫入權限 withResponse 類的特征其大小一般為 512 字節,當然這些都是取決于設備測的設置;
當我們單次發送的數據字節長度大于 maxLength 時,我們就需要采用分包的方式來發送數據了,
分包發送的邏輯類似于下面
這邊延時主要是設備側的接收模塊接收數據以及處理能力有限
外圍設備測和中心設備(大部分情況下是手機)保持藍牙連接的狀態下,如果長時間不產生交互,藍牙就會斷開,所以為了保持兩者持續的連接狀態,需要做保活處理,也就是需要持續的發送心跳包(watchdog)。相應的處理是使用一個定時器定時向設備側發送符合設備協議格式的心跳包。
斷開連接很簡單,只需要調用 [self.centralManager cancelPeripheralConnection:peripheral] 傳入需要斷開連接的設備對象就行了。斷開連接時會自動調用 centralManager:didDisconnectPeripheral:error: 代理方法。
按照之前的慣例,當error為nil時表示斷開成功,error不為nil時斷開失敗。這種理解是錯誤的。
當你調用 cancelPeripheralConnection: 方法(主動斷開)斷開連接時error為nil ; 沒有調用這個方法(異常斷開)而斷開時error返回的是異常斷開的原因。也可以理解為主動調用斷開連接方法一定會斷開
接下來就是斷開重連的問題了,對藍牙功能進行封裝時肯定少不了斷開重連。首先斷開時可通過上面的代理方法的error是否為nil判斷是否是異常斷開,一般情況下異常斷開時是需要重連的
原因就是當設備斷開連接后 peripheral.services 為nil了,當然 service.characteristics 也是nil,所以需要在斷開連接時把保存這個設備對應的服務和特征全部清除,然后在連接成功時重新過一遍發現服務和發現特征的流程就好了。
iOS7 開始,Apple加入了Beacon圍欄檢測的API, ( iBeacon-維基百科 ), 其工作方式是,配備有低功耗藍牙(BLE)通信功能的設備使用 BLE 技術向周圍發送自己特有的 ID,接收到該 ID 的應用軟件會根據該 ID 采取一些行動。比如,在店鋪里設置 iBeacon 通信模塊的話,便可讓 iPhone 和 iPad 上運行一資訊告知服務器,或者由服務器向顧客發送折扣券及進店積分, 或者公司的手機打卡,只要手機靠近打卡器一定范圍,手機測就向打開器發送打卡信息,從而自動打卡。這種場景還有很多。 其中一個最重要的功能就是App的喚醒功能(殺死后也能喚醒)
舉一個我們的例子,我們的產品業務場景就是在進入車輛以后,需要使用藍牙連接我們的后裝車載設備以采集車輛信息和駕駛行為行程等,這里有一個問題就是在App被殺死的情況下如何喚醒App, 因為不可能要求用戶每次都主動去打開App,這樣體驗太差。我們的做法是通過iBeacon,當我們的車輛點火以后,設備測通電,發出 iBeacon廣播 ,App實現監聽iBeacon相關功能后就可以喚醒我們App,然后在相應的回調的處理一些事情,比如通過藍牙連接設備。這里的前提條件是我們的硬件設備測包含iBeacon模塊,具有iBeacon功能,而且對iBeacon的廣播頻率也有一定的要求,長了可能喚醒的功能會不穩定,官方建議的好像是100ms,頻率超高越耗電,但可以讓手機或其它監聽設備越快地發現iBeacon。標準的BLE廣播距離是100m,這使Beacon在室內位置跟蹤場景下的效果更理想。
關于iBeacon更多的使用及介紹請參考
蘋果核 - iOS端近場圍欄檢測(一) ——iBeacon
iBeacon技術初探
一、屬性修飾符
讀寫屬性: (readwrite/readonly)
語義特性:(內存有關):(assign/retain/copy)
原子特性:(和線程安全有關): (atomicit/nonatomic)
readonly:只讀,屬性只會生成getter方法,不會生成setter.
readwrite:既可讀又可寫.屬性自動生成setter和getter方法.(默認的讀寫特性)
getter= 方法名:指定生成getter方法時的方法名.
setter= 方法名:指定生成setter方法時的方法名.
assign: 默認類型,setter方法直接賦值,而不進行retain操作,也可以只針對對象,只是做簡單的賦值操作. 默認的語義特性.
retain: 針對于對象類型,setter方法對參數進行release舊值,再retain新值。
copy: setter方法進行Copy操作,與retain一樣, 針對于對象類型,會拷貝一個新的對象,將新的對象的引用計數加1
nonatomic: 禁止多線程,變量保護,提高性能
atomic:原子特性,保證線程安全.系統默認的原子特性.
weak:指針指向的地址一旦被釋放,這些指針都將被賦值為nil。這樣的好處能有效的防止野指針。消除循環引用 。
二、 @dynamic 關鍵字
@dynamic dynamicStr; // 告訴編譯器,不自定生成getter和setter方法,避免編譯期間產生警告,然后由自己實現存取方法。
三、 @synthesize 關鍵字
@synthesize strongStr = _strongStr; // 可以定義 與變量名不相同的getter和setter的命名,籍此來保護變量不會被不恰當的訪問, 編譯器期間,讓編譯器自動生成getter/setter方法 當有自定義的存或取方法時,自定義會屏蔽自動生成該方法
四、重定義setter方法getter方法
// 重定義setter方法
// 重定義getter方法
五、不可變字符串 NSString
// 運行log日志:
2021-03-11 17:30:08.112340+0800 TestObject-C[93449:1623723] temp1: 不可變字符串, 0x10df9e778
2021-03-11 17:30:08.112529+0800 TestObject-C[93449:1623723] str: 不可變字符串, 0x10df9e778
2021-03-11 17:30:08.112610+0800 TestObject-C****[****93449:1623723****]**** strongStr: ****不可變字符串****, 0x10df9e778
六、可變字符串 NSMutableString
// 一、將不可變字符串賦值給可變字符串對象。
// 賦值可變字符串對象后,對象仍然是不可變對象
2021-03-11 17:30:08.114159+0800 TestObject-C[93449:1623723] mTemp: 不 可變字符串1, 0x10df9e878
2021-03-11 17:30:08.114393+0800 TestObject-C[93449:1623723] mCopyStr: 不 可變字符串1, 0x10df9e878
2021-03-11 17:30:08.114697+0800 TestObject-C****[****93449:1623723****]**** mStrongStr: 不 可變字符串****1, 0x10df9e878
// 一、將可變字符串賦值給可變字符串對象。
2021-03-11 19:38:34.493763+0800 TestObject-C[95274:1718783] mTemp2: 可變字符串2, 0x600002710ea0, __NSCFString
2021-03-11 19:38:34.493923+0800 TestObject-C[95274:1718783] mCopyStr: 可變字符串2, 0x6000027110e0, __NSCFString
2021-03-11 19:38:34.494037+0800 TestObject-C****[****95274:1718783****]**** mStrongStr: ****可變字符串****2, 0x600002710ea0, __NSCFString
2021-03-11 19:38:34.494422+0800 TestObject-C[95274:1718783] mTemp2: 可變字符串211, 0x600002710ea0, __NSCFString
2021-03-11 19:38:34.494697+0800 TestObject-C[95274:1718783] mCopyStr: 可變字符串2, 0x6000027110e0, __NSCFString
2021-03-11 19:38:34.494903+0800 TestObject-C****[****95274:1718783****]**** mStrongStr: ****可變字符串****211, 0x600002710ea0, __NSCFString
七、富文本字符串 NSMutableAttributedString
2021-03-11 19:34:52.041131+0800 TestObject-C[95207:1715249] attriStr: 我是富文本我是富文本我是富文本我是富文本, 0x600000a5bc00, NSConcreteMutableAttributedString
2021-03-11 19:34:52.041307+0800 TestObject-C[95207:1715249] mutableAttri: 我是富文本我是富文本我是富文本我是富文本, 0x600000a5be40, NSConcreteAttributedString
2021-03-11 19:34:52.041425+0800 TestObject-C****[****95207:1715249****]**** mutableStrongAttri: ****我是富文本我是富文本我是富文本我是富文本****, 0x600000a5bc00, NSConcreteMutableAttributedString
2021-03-11 19:34:52.041943+0800 TestObject-C[95207:1715249] attriStr: 我是富文本我是富文本我是富文本我是富文本---我是新添加的, 0x600000a5bc00, NSConcreteMutableAttributedString
2021-03-11 19:34:52.042281+0800 TestObject-C****[****95207:1715249****]**** mutableStrongAttri: ****我是富文本我是富文本我是富文本我是富文本****---****我是新添加的****, 0x600000a5bc00, NSConcreteMutableAttributedString
八、不可變數組NSArray
//一、 不可變數組賦值NSArray的對象
2021-03-11 19:04:42.636207+0800 TestObject-C[94739:1689350] arr: (1, 2,
3), 0x600001d5c8d0
2021-03-11 19:04:42.636411+0800 TestObject-C[94739:1689350] persons: ( 1, 2, 3), 0x600001d5c8d0
2021-03-11 19:04:42.636538+0800 TestObject-C[94739:1689350] students: (1, 2, 3), 0x600001d5c8d0
2021-03-11 19:04:42.636646+0800 TestObject-C[94739:1689350] arr: (1, 2, 3), 0x600001d5c8d0
2021-03-11 19:04:42.636767+0800 TestObject-C[94739:1689350] students: (1, 2,3), 0x600001d5c8d0, __NSArrayI
// 二、不可變數組賦值給NSMutableArray的對象
**2021-03-11 19:15:59.046728+0800 TestObject-C[94934:1699039] arr: (1,2,3), 0x600002f6c000
2021-03-11 19:15:59.046878+0800 TestObject-C[94934:1699039] cars: (1, 2,3), 0x600002f6c000, __NSArrayI2021-03-11 19:15:59.046982+0800 TestObject-C[94934:1699039] dogs: (1,2,3), 0x600002f6c000, __NSArrayI
九、可變數組 NSMutableArray
2021-03-11 19:22:39.183745+0800 TestObject-C[95044:1705082] arr2: (2,4,10,12), 0x600000fefea0
2021-03-11 19:22:39.184067+0800 TestObject-C[95044:1705082] cars: (2,4,10), 0x600000fef240, __NSArrayI
**2021-03-11 19:22:39.184272+0800 TestObject-C[95044:1705082] dogs: (2,4,10,12), 0x600000fefea0, __NSArrayM
十、不可變字典 NSDictionary
// 不可變數組賦值給NSDictionary對象
2021-03-11 19:25:32.789615+0800 TestObject-C[95102:1708378] dic: {key1 = 1;key2 = value;}, 0x6000028799c0**
2021-03-11 19:25:32.789801+0800 TestObject-C[95102:1708378] personDic: { key1 = 1;key2 = value;}, 0x6000028799c0, __NSDictionaryI
2021-03-11 19:25:32.789919+0800 TestObject-C[95102:1708378] studentDic: { key1 = 1;key2 = value;}, 0x6000028799c0, __NSDictionaryI
十一、可變字典 NSMutableDictionary
2021-03-11 19:59:28.739545+0800 TestObject-C[96373:1735182] mDic: { key1 = 10;key2 = value2;}, 0x6000017f0700, __NSDictionaryM
**2021-03-11 19:59:28.740177+0800 TestObject-C[96373:1735182] carDic: {key1 = 10;key2 = value2;}, 0x6000017f07a0, __NSFrozenDictionaryM
2021-03-11 19:59:28.740359+0800 TestObject-C[96373:1735182] dogDic: { key1 = 10;key2 = value2;}, 0x6000017f0700, __NSDictionaryM
2021-03-11 20:05:24.028840+0800 TestObject-C[96469:1740141] mDic: {key1 = 10; key2 = value2;key4 = value4;}, 0x6000011bd7e0, __NSDictionaryM
2021-03-11 20:05:24.028930+0800 TestObject-C[96469:1740141] carDic: { key1 = 10; key2 = value2;}, 0x6000011bd820, __NSFrozenDictionaryM
2021-03-11 20:05:24.029028+0800 TestObject-C[96469:1740141] dogDic: {key1 = 10;key2 = value2;key4 = value4;}, 0x6000011bd7e0, __NSDictionaryM
十二、不可變集合 NSSet
// 一、不可變NSSet賦值給 NSSet對象
2021-03-11 20:09:49.418694+0800 TestObject-C[96545:1744249] set: {( 1,2,3)}, 0x600003fd2e80, __NSSetI
2021-03-11 20:09:49.418826+0800 TestObject-C[96545:1744249] personSet: {(1,2,3)}, 0x600003fd2e80, __NSSetI
2021-03-11 20:09:49.418914+0800 TestObject-C[96545:1744249] studentSet: {(1,2,3)}, 0x600003fd2e80, __NSSetI
// 二、不可變NSSet賦值給 NSMutableSet對象
2021-03-11 20:09:49.419281+0800 TestObject-C[96545:1744249] carSet: {(1,2,3)}, 0x600003fd2e80, __NSSetI
2021-03-11 20:09:49.419362+0800 TestObject-C[96545:1744249] dogSet: {(1, 2,3)}, 0x600003fd2e80, __NSSetI
十三、可變集合 NSMutableSet
2021-03-11 20:18:06.896997+0800 TestObject-C[96705:1752827] mSet: {(3,1,2,5)}, 0x600001e0a700, __NSSetM
2021-03-11 20:18:06.897218+0800 TestObject-C[96705:1752827] carSet: {( 1,2,3)}, 0x600001014bd0, __NSSetI
2021-03-11 20:18:06.897340+0800 TestObject-C[96705:1752827] dogSet: {(3,1,2, 5)}, 0x600001e0a700, __NSSetM
Xcode 8.2.1
前文說過,NSArray和NSDictionary只能存入OC對象。不信我們可以做個試驗:將一個int類型或者是NSInteger放入NSMutableArray里面。(NSInteger和int的差別:NSInteger會根據系統的位數32or64,自動選擇int的最大數值int or long,這樣我們就不用考慮設備是32位還是64位系統)
這樣是會編譯出錯的,存入不成功。
那怎么辦呢?所以,我們需要將int或者NSInteger類型轉換成NSNumber(OC對象),然后再存入NSArray中。
NSNumber可以轉換一系列的基礎數字類型(char、int、float、long、bool等等),還提供了一個compare方法來將NSNumber對象進行數值排序。
我們來看看NSNumber有哪些要掌握的知識點:
運行結果如下:
之所以把NSNumber和NSValue放到同一篇,是因為NSNumber是NSValue的子類,NSValue除了能夠包裝NSNumber能夠包裝的基礎數字類型外,還能夠包裝系統框架提供的CGRect/CGPoint/CGSize等數據結構,也可以是自己定義的struct。最終也能放入數組。
同樣,我們來看看它的應用:
運行結果:
當前題目:ios開發知識點,簡述ios的特點
鏈接地址:http://vcdvsql.cn/article10/dsdgsgo.html
成都網站建設公司_創新互聯,為您提供響應式網站、品牌網站制作、定制開發、網站導航、標簽優化、定制網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯