被面試問的問題, 和網(wǎng)上找到的我覺得不錯(cuò)的問題
會(huì)保持更新 -- 因都寫在一起了, 所以可能會(huì)穿插添加. 請(qǐng)諒解
iOS-多線程
常見的幾種線程鎖 / 保證線程安全
- @synchronized 適用線程不多,任務(wù)量不大的多線程加鎖
- NSLock 常用鎖 性能一般
- dispatch_semaphore_t GCD信號(hào)鎖,性能不錯(cuò)
- OSSpinLock 性能非常高 但是線程出現(xiàn)了問題
Run字輩
簡單講一下Runtime
Runtime 它是OC的運(yùn)行時(shí), 其中最重要的就是消息機(jī)制 C語言是編譯時(shí)就已經(jīng)確定了如何調(diào)用.
OC是在運(yùn)行的時(shí)候才會(huì)確定
當(dāng)我們調(diào)用了一個(gè)方法的時(shí)候 運(yùn)行過程是?
- Runtime會(huì)將我們的方法調(diào)用 轉(zhuǎn)為消息發(fā)送
objc_msgSend
, 并且把方法的調(diào)用者和方法選擇器 作為參數(shù)一起傳遞過去 - 方法的調(diào)用者會(huì)通過isa指針查找到該方法所屬的類, 然后在Cache 或者 Method_Lists中查找該方法, 如果有則調(diào)用執(zhí)行
- 如果沒有找到該方法, 則通過SuperClass 繼續(xù)像父類查找(如何到NSObject還未查找到則進(jìn)入消息轉(zhuǎn)發(fā))
動(dòng)態(tài)方法解析
一般情況下程序Carsh 類似
unrecognized selector sent to instance 內(nèi)存地址
在Crash之前Runtime會(huì)給我們補(bǔ)救的機(jī)會(huì)(消息轉(zhuǎn)發(fā))
- 檢測(cè)這個(gè) selector 是不是要忽略的。比如 Mac OS X 開發(fā),有了垃圾回收就不理會(huì) retain,release 這些函數(shù)了
- 檢測(cè)這個(gè) target 是不是 nil 對(duì)象。ObjC 的特性是允許對(duì)一個(gè) nil 對(duì)象執(zhí)行任何一個(gè)方法不會(huì) Crash,因?yàn)闀?huì)被忽略掉
- 如果上面兩個(gè)都過了,那就開始查找這個(gè)類的 IMP,先從 cache 里面找,完了找得到就跳到對(duì)應(yīng)的函數(shù)去執(zhí)行. 如果 cache 找不到就找一下方法分發(fā)表
- 如果分發(fā)表找不到就到超類的分發(fā)表去找,一直找,直到找到NSObject類為止
如果還找不到就要開始進(jìn)入消息轉(zhuǎn)發(fā)了,消息轉(zhuǎn)發(fā)的大致過程如圖:
- 進(jìn)入
resolveInstanceMethod:
方法,詢問是否動(dòng)態(tài)添加方法,如果返回Yes, 通過class_addMethod
動(dòng)態(tài)添加函數(shù)方法, 消息的處理完畢, 此流程完畢. 返回No 進(jìn)入 2 - 進(jìn)入
ForwardTargetForSelector:
方法, 用于指定那個(gè)對(duì)象來響應(yīng)這個(gè)Selector
, 如果返回某個(gè)對(duì)象, 該對(duì)象調(diào)用此方法, 此流程完畢. 返回nil 進(jìn)入 3 - 通過
methodSignatureForSelector:
來指定方法簽名,返回nil, 表示不處理, 返回簽名(通過NSMethodSignature signatureWithObjcType:"v@:"
來進(jìn)行重新簽名)則進(jìn)入 4 - 調(diào)用
forwardInvlication:
方法, 通過invocation
修改實(shí)現(xiàn)方法,修改響應(yīng)對(duì)象等。
Runtime 能做什么
- 字典和模型相互轉(zhuǎn)換
- 方法交換
- 給分類添加屬性
- 自動(dòng)歸解檔
Category 原理
通過
attachCategoryMethods
這個(gè)函數(shù)來處理的, 將類中舊方法和Category新添加的方法整合成一個(gè)新的方法列表, 并賦值給method_lists
或者method_list
. 主類中的方法和 Category 中的方法在 runtime 看來并沒有區(qū)別,它們是被同等對(duì)待的,都保存在主類的方法列表中。我們需要調(diào)用時(shí)引入頭文件, 是要"照顧"編輯器大大的感受而已...
Runtime 常見的定義
- IMP implementation 實(shí)現(xiàn)的意思 指向一個(gè)方法實(shí)現(xiàn)的指針
Runloop
一般來講,一個(gè)線程一次只能執(zhí)行一個(gè)任務(wù),執(zhí)行完成后線程就會(huì)退出。如果我們需要一個(gè)機(jī)制,讓線程能隨時(shí)處理事件但并不退出
NSTime 為什么在滑動(dòng)UIScrollView時(shí)候會(huì)暫停
因?yàn)镽unloop 原因, 為了保證UIScrollView滑動(dòng)時(shí)候的流暢度, 會(huì)將Runloop的Mode切換為
TrackingRunLoopMode
, 這時(shí)候NSTimer就不會(huì)得到回調(diào). 只需要將NSTimer的model 改為commonModeItems
即可了
NSAutoreleasePool
NSAutoreleasePool 類被用來支持自動(dòng)引用計(jì)數(shù)內(nèi)存管理系統(tǒng).
autoreleased 對(duì)象什么時(shí)候釋放
對(duì)象創(chuàng)建后會(huì)被添加到最近的
autoReleasePool
中, 只有這個(gè)autoReleasePool
自身drain的時(shí)候,autoReleasePool
中的對(duì)象才會(huì)被release
根據(jù)蘋果官方文檔中對(duì) NSAutoreleasePool 的描述,我們可知,在主線程的 NSRunLoop 對(duì)象(在系統(tǒng)級(jí)別的其他線程中應(yīng)該也是如此,比如通過
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
獲取到的線程)的每個(gè) event loop 開始前,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè) autoreleasepool ,并在 event loop 結(jié)束時(shí) drain 。我們上面提到的場景 1 中創(chuàng)建的 autoreleased 對(duì)象就是被系統(tǒng)添加到了這個(gè)自動(dòng)創(chuàng)建的 autoreleasepool 中,并在這個(gè) autoreleasepool 被 drain 時(shí)得到釋放
AutoreleasePoolPage
那這里的 AutoreleasePoolPage 是什么東西呢?其實(shí),autoreleasepool 是沒有單獨(dú)的內(nèi)存結(jié)構(gòu)的,它是通過以 AutoreleasePoolPage 為結(jié)點(diǎn)的雙向鏈表來實(shí)現(xiàn)的。
autoreleasepool 的運(yùn)行過程可以簡單地理解為objc_autoreleasePoolPush()
、[對(duì)象 autorelease]
和objc_autoreleasePoolPop(void *)
三個(gè)過程
和線程之間的關(guān)系
每一個(gè)線程都會(huì)維護(hù)自己的 autoreleasepool 堆棧。換句話說 autoreleasepool 是與線程緊密相關(guān)的,每一個(gè) autoreleasepool 只對(duì)應(yīng)一個(gè)線程。
iOS手勢(shì)問題
響應(yīng)者鏈
處理事件響應(yīng)者先后順序鏈. 有些時(shí)候,Touch后系統(tǒng)通過hit test 機(jī)制找到了觸碰到的Initial View,但是Initial view并沒有或者無法正常處理此次Touch。這個(gè)時(shí)候,系統(tǒng)便會(huì)通過響應(yīng)者鏈尋找下一個(gè)響應(yīng)者,以對(duì)此次Touc 進(jìn)行響應(yīng)。
Hit-Test機(jī)制
當(dāng)你點(diǎn)擊屏幕一個(gè)點(diǎn)時(shí), 這個(gè)操作由硬件系統(tǒng)傳遞到操作系統(tǒng), 然后封裝為一個(gè)事件(Event) , 由UIApplication->UIWindows->RootView到最接近你手指的View來響應(yīng)事件
子類超出父類邊緣時(shí)候, 亦可以響應(yīng)事件(正常是不可以的, 你需要重寫
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
這個(gè)方法)
iOS關(guān)鍵字
static聲明局部變量
static 聲明的局部變量, 會(huì)改變它的存儲(chǔ)方式(生命周期), 使變量成為靜態(tài)變量, 在編譯時(shí)候就會(huì)分配內(nèi)存, 知道程序退出才會(huì)釋放內(nèi)存. 這樣就帶有記憶的能力, 可以記錄上一次的數(shù)據(jù), 但是因?yàn)樽兞窟€是局部變量, 所有只能在其代碼塊內(nèi)使用.
static 聲明外部變量
用static聲明外部變量,其本身就是靜態(tài)變量,這只會(huì)改變其連接方式,使其只在本文件內(nèi)部有效,而其他文件不可連接或引用該變量。
作用域函數(shù)
使用static用于函數(shù)定義時(shí),對(duì)函數(shù)的連接方式產(chǎn)生影響,使得函數(shù)只在本文件內(nèi)部有效,對(duì)其他文件是不可見的。這樣的函數(shù)又叫作靜態(tài)函數(shù)。使用靜態(tài)函數(shù)的好處是,不用擔(dān)心與其他文件的同名函數(shù)產(chǎn)生干擾,另外也是對(duì)函數(shù)本身的一種保護(hù)機(jī)制。
網(wǎng)絡(luò)部分
簡單講一下Socket
Socket 套接字, 他本身不是協(xié)議, 是對(duì)TCP/IP協(xié)議的封裝, 通過Socket才可以使用TCP/IP協(xié)議.
建立socket連接. 服務(wù)器監(jiān)聽->客戶端進(jìn)行請(qǐng)求->連接確認(rèn)
在iOS中, 一般使用CocoaAsyncSocket 這個(gè)庫來使用Socket
簡單講一下HTTP請(qǐng)求,以及GET和POST的區(qū)別
HTTP 請(qǐng)求
HTTP是計(jì)算機(jī)通過網(wǎng)絡(luò)進(jìn)行通信的原則. HTTP是一中無狀態(tài)協(xié)議(即Web服務(wù)器和Web服務(wù)器間不用建立持久的鏈接,當(dāng)客戶端發(fā)送請(qǐng)求,服務(wù)器端返回響應(yīng),鏈接就關(guān)閉了).
一次完整的通信過程 需要經(jīng)歷7個(gè)步驟
- 建立TCP鏈接
- Web瀏覽器向Web服務(wù)器發(fā)送請(qǐng)求命令
- Web瀏覽器發(fā)送請(qǐng)求頭信息
- Web服務(wù)器應(yīng)答
- Web服務(wù)器發(fā)送應(yīng)答頭信息
- Web服務(wù)器向?yàn)g覽器發(fā)送數(shù)據(jù)
- Web服務(wù)器關(guān)閉TCP鏈接
GET和POST區(qū)別
'標(biāo)準(zhǔn)答案'
- GET在瀏覽器回退時(shí)是無害的,而POST會(huì)再次提交請(qǐng)求。
- GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以。
- GET請(qǐng)求會(huì)被瀏覽器主動(dòng)cache,而POST不會(huì),除非手動(dòng)設(shè)置。
- GET請(qǐng)求只能進(jìn)行url編碼,而POST支持多種編碼方式。
- GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會(huì)被保留。
- GET請(qǐng)求在URL中傳送的參數(shù)是有長度限制的,而POST么有。
- 對(duì)參數(shù)的數(shù)據(jù)類型,GET只接受ASCII字符,而POST沒有限制。
- GET比POST更不安全,因?yàn)閰?shù)直接暴露在URL上,所以不能用來傳遞敏感信息。
- GET參數(shù)通過URL傳遞,POST放在Request body中。
裝B答案
無論是GET還是POST 本質(zhì)上都是TCP鏈接,并無差別.
但是他們有重要的區(qū)別在于GET方式請(qǐng)求產(chǎn)生一個(gè)TCP數(shù)據(jù)包;POST是兩個(gè).
對(duì)于GET方式的請(qǐng)求,瀏覽器會(huì)把http header和data一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù)
而對(duì)于POST,瀏覽器先發(fā)送header,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))。 并不是所有瀏覽器都會(huì)在POST中發(fā)送兩次包,F(xiàn)irefox就只發(fā)送一次。在網(wǎng)絡(luò)環(huán)境好的情況下,發(fā)一次包的時(shí)間和發(fā)兩次包的時(shí)間差別基本可以無視。而在網(wǎng)絡(luò)環(huán)境差的情況下,兩次包的TCP在驗(yàn)證數(shù)據(jù)包完整性上,有非常大的優(yōu)點(diǎn)。
HTTPS的加密方式
HTTPS的加密方式
對(duì)稱加密
對(duì)稱加密是指加密和解密使用相同密鑰的加密算法。它要求發(fā)送方和接收方在安全通信之前,商定一個(gè)密鑰。對(duì)稱算法的安全性依賴于密鑰,泄漏密鑰就意味著任何人都可以對(duì)他們發(fā)送或接收的消息解密,所以密鑰的保密性對(duì)通信至關(guān)重要。
優(yōu)點(diǎn):算法公開、計(jì)算量小、加密速度快、加密效率高。
-
缺點(diǎn):
交易雙方都使用同樣鑰匙,安全性得不到保證;
每對(duì)用戶每次使用對(duì)稱加密算法時(shí),都需要使用其他人不知道的惟一鑰匙,這會(huì)使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級(jí)數(shù)增長,密鑰管理成為用戶的負(fù)擔(dān)。
能提供機(jī)密性,但是不能提供驗(yàn)證和不可否認(rèn)性。
非對(duì)稱加密
這種加密或許理解起來比較困難,這種加密指的是可以生成公鑰和私鑰。凡是公鑰加密的數(shù)據(jù),公鑰自身不能解密,而需要私鑰才能解密;凡是私鑰加密的數(shù)據(jù),私鑰不能解密,需要公鑰才能解密(比如說RSA)
非對(duì)稱加密相比對(duì)稱加密更加安全,但也存在兩個(gè)明顯缺點(diǎn):
CPU計(jì)算資源消耗非常大。一次完全TLS握手,密鑰交換時(shí)的非對(duì)稱解密計(jì)算量占整個(gè)握手過程的90%以上。而對(duì)稱加密的計(jì)算量只相當(dāng)于非對(duì)稱加密的0.1%,如果應(yīng)用層數(shù)據(jù)也使用非對(duì)稱加解密,性能開銷太大,無法承受。
非對(duì)稱加密算法對(duì)加密內(nèi)容的長度有限制,不能超過公鑰長度。比如現(xiàn)在常用的公鑰長度是2048位,意味著待加密內(nèi)容不能超過256個(gè)字節(jié)。
所以公鑰加密目前只能用來作密鑰交換或者內(nèi)容簽名,不適合用來做應(yīng)用層傳輸內(nèi)容的加解密
流程
首先服務(wù)器端用非對(duì)稱加密(RSA)產(chǎn)生公鑰和私鑰。然后把公鑰發(fā)給客 戶端,路徑或許有人會(huì)截取,但是沒有用,因?yàn)橛霉€加密的文件只有私鑰可以解密,而私鑰永遠(yuǎn)都不會(huì)離開服務(wù)器的。當(dāng)公鑰到達(dá)客戶端之后,客戶端會(huì)用對(duì)稱加密產(chǎn)生一個(gè)秘鑰并且用公鑰來加密發(fā)送給服務(wù)器端,這個(gè)秘鑰就是以后用來通信的鑰匙。這樣服務(wù)器端收到公鑰加密的秘鑰時(shí)就可以用私鑰來解公鑰從而獲得秘鑰。這樣的話客戶端和服務(wù)器端都獲得了秘鑰,信息交流相對(duì)是安全的
<div align = "center">
<img src = "http://upload-images.jianshu.io/upload_images/535139-206dfc1d526b4b1f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" align = "center" > </img>
</div>
? 聽起來確實(shí)是挺安全的,但實(shí)際上,還有一種更惡劣的攻擊是這種方法無 法防范的,這就是傳說中的“中間人攻擊”。在身份認(rèn)證的過程中,出現(xiàn)了一個(gè)“中間人”攔截我們的信息,他有意想要知道你們的消息。我們將這個(gè)中間人稱為M。當(dāng)服務(wù)器第一次給客戶端發(fā)送公鑰的時(shí)候,途徑M。M知道你要進(jìn)行密鑰交換了,它把公鑰扣了下來,假裝自己是客戶端,偽造了一個(gè)偽秘鑰(對(duì)稱加密產(chǎn)生的),然后用服務(wù)器發(fā)來的公鑰加密了偽秘鑰發(fā)還給服務(wù)器,這樣服務(wù)器以為和客戶端完成了密鑰交換,實(shí)際上服務(wù)器是和M完成了密鑰交換(獲得了偽秘鑰)。同時(shí)M假扮成服務(wù)器自行用非對(duì)稱加密產(chǎn)生偽公鑰和偽私鑰,與客戶端進(jìn)行秘鑰交換,拿到客戶端發(fā)送過來的秘鑰。現(xiàn)在客戶端拿著秘鑰,M拿著秘鑰和為偽秘鑰,服務(wù)器拿著偽秘鑰,整個(gè)交流的過程就是:
<div align = "center">
<img src = "https://user-gold-cdn.xitu.io/2017/6/21/5d38312283e1e59840315ba2099aff38 " align = "center" > </img>
</div>
這種問題就需要CA證書去解決. (應(yīng)該可以滿足大部分面試問題不再過多深入)
持續(xù)化存儲(chǔ)方式
- NSUserDefaults
- plist
- NSKeyedArchiver
- SQL
- CoreData
- Realm(新興數(shù)據(jù)庫, 暫時(shí)沒接觸)
一些三方實(shí)現(xiàn)過程
SDWebImage
- 入口 setImageWithURL:placeholderImage:options: 會(huì)先把 placeholderImage 顯示,然后 SDWebImageManager 根據(jù) URL 開始處理圖片。
- 進(jìn)入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交給 SDImageCache 從緩存查找圖片是否已經(jīng)下載 queryDiskCacheForKey:delegate:userInfo:.
- 先從內(nèi)存圖片緩存查找是否有圖片,如果內(nèi)存中已經(jīng)有圖片緩存,SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
- SDWebImageManagerDelegate 回調(diào) webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示圖片。
- 如果內(nèi)存緩存中沒有,生成 NSInvocationOperation 添加到隊(duì)列開始從硬盤查找圖片是否已經(jīng)緩存。
- 根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進(jìn)行的操作,所以回主線程進(jìn)行結(jié)果回調(diào) notifyDelegate:。
- 如果上一操作從硬盤讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小,會(huì)先清空內(nèi)存緩存)。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:。進(jìn)而回調(diào)展示圖片。
- 如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片,需要下載圖片,回調(diào) imageCache:didNotFindImageForKey:userInfo:。
- 共享或重新生成一個(gè)下載器 SDWebImageDownloader 開始下載圖片。
- 圖片下載由 NSURLConnection 來做,實(shí)現(xiàn)相關(guān) delegate 來判斷圖片下載中、下載完成和下載失敗。
- connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進(jìn)度加載效果。
- connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理。
- 圖片解碼處理在一個(gè) NSOperationQueue 完成,不會(huì)拖慢主線程 UI。如果有需要對(duì)下載的圖片進(jìn)行二次處理,最好也在這里完成,效率會(huì)好很多。
- 在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成, imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader。
- imageDownloader:didFinishWithImage: 回調(diào)給 SDWebImageManager 告知圖片下載完成。
- 通知所有的 downloadDelegates 下載完成,回調(diào)給需要的地方展示圖片。
- 將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤緩存同時(shí)保存。寫文件到硬盤也在以單獨(dú) NSInvocationOperation 完成,避免拖慢主線程。
- SDImageCache 在初始化的時(shí)候會(huì)注冊(cè)一些消息通知,在內(nèi)存警告或退到后臺(tái)的時(shí)候清理內(nèi)存圖片緩存,應(yīng)用結(jié)束的時(shí)候清理過期圖片。
- SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
- SDWebImagePrefetcher 可以預(yù)先下載圖片,方便后續(xù)使用。
優(yōu)化問題
iOS離屏渲染
直接將圖層合成到幀的緩沖區(qū)中(在屏幕上)比先創(chuàng)建屏幕外緩沖區(qū),然后渲染到紋理中,最后將結(jié)果渲染到幀的緩沖區(qū)中要廉價(jià)很多。因?yàn)檫@其中涉及兩次昂貴的環(huán)境轉(zhuǎn)換(轉(zhuǎn)換環(huán)境到屏幕外緩沖區(qū),然后轉(zhuǎn)換環(huán)境到幀緩沖區(qū))。觸發(fā)離屏渲染后這種轉(zhuǎn)換發(fā)生在每一幀,在界面的滾動(dòng)過程中如果有大量的離屏渲染發(fā)生時(shí)會(huì)嚴(yán)重影響幀率
iOS中可能會(huì)觸發(fā)離屏渲染的操作
- mask
- shadow
- group opacity
- edge antialiasing
在iOS 8之前 Core Graphics 也會(huì)觸發(fā)離屏渲染, 但是不是GPU離屏渲染是, Core Graphics 繪制 API 是在 CPU 上執(zhí)行,觸發(fā)的是 CPU 版本的離屏渲染。
layer.cornerRaius > 0 是否會(huì)觸發(fā)離屏渲染
答案是不會(huì). 只有它和
layer.masksToBounds = true
一起才會(huì)觸發(fā)
shouldRasterize = YES 是否會(huì)觸發(fā)呢
是
但是他較為特殊, 他會(huì)將離屏渲染的的同時(shí), 會(huì)將光柵化的內(nèi)容緩存起來, 如果layer 或者 SubLayer 未發(fā)生變化, 下一幀會(huì)拿來直接使用.
當(dāng)你使用光柵化時(shí),你可以開啟“Color Hits Green and Misses Red”來檢查該場景下光柵化操作是否是一個(gè)好的選擇。綠色表示緩存被復(fù)用,紅色表示緩存在被重復(fù)創(chuàng)建。
對(duì)于經(jīng)常變動(dòng)的內(nèi)容,這個(gè)時(shí)候不要開啟,否則會(huì)造成性能的浪費(fèi)(比如TableView)
Crash問題
什么情況下會(huì)產(chǎn)生崩潰日志
- 應(yīng)用中有Bug 崩潰
- Watchdog 超時(shí)機(jī)制. 如果用戶強(qiáng)制退出
- 低內(nèi)存日志
Crash收集的幾種方式
- 簡單可以自己寫一個(gè)方法 之后在寫入詞磁盤中, 下次進(jìn)入時(shí)候上傳服務(wù)器, 之后刪除
void handleException(NSException *exception) {
NSArray *callStack = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
}
- 使用Xcode自帶的工具.Windows->Organizer->選擇你需要的App->Crashes會(huì)自己動(dòng)下載崩潰 直接打開就可以了
- 使用第三方框架例如Bugly等
Crash分析
一般采用 .Crash 文件 + .dSYM文件 + symbolicatecrash(Xcode自帶工具) 輸出.log
詳細(xì)請(qǐng)看參考 )
其他知識(shí)
在不知道二進(jìn)制文件格式情況下如何區(qū)分文件
可以通過二進(jìn)制頭識(shí)別文件類型(說幾個(gè)簡單的 不好意思 一個(gè)沒記住)或者UE等工具打開