国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

FBMemoryProfiler使用

2019-11-06 09:42:40
字體:
來源:轉載
供稿:網友

原文地址:http://ifujun.com/fbmemoryPRofiler-shi-yong-ji-chu-jiao-cheng/

FBMemoryProfiler是Facebook開源的一款用于分析iOS內存使用和檢測循環引用的工具庫。

在上一篇[譯文]在iOS上自動檢測內存泄露中,Facebook講解了FBMemoryProfiler的核心原理。鑒于有人在評論里問怎么使用,我這里就簡單介紹一下。

安裝

CocoaPods

建議使用Cocoapods安裝,只需要在pod文件中,添加這么一句就行:

pod 'FBMemoryProfiler'

FBMemoryProfiler最低支持iOS8,所以如果你的pod文件上最低要求是6或者7的話,是無法直接安裝的。所以,建議在開發分支或者如果你有多個target的話,在開發的target上添加FBMemoryProfiler,在生產的target上不需要添加FBMemoryProfiler

我一般習慣于有兩個target,一個用于開發,里面可能會包含Reveal、蒲公英等的庫,而這在生產包中是不必要的,另一個用于生產,只用于打生產包。

所以我的pod文件可能是這樣的:

# Uncomment this line to define a global platform for your projectplatform :ios, '8.0'# Uncomment this line if you're using Swift# use_frameworks!target 'FBMemoryProfilerTest' doendtarget 'FBMemoryProfilerTest_Dev' dopod 'FBMemoryProfiler'end

安裝成功之后,打開對于的.xcworkspace文件即可。

Carthage

如果你的app從iOS8開始支持的話,你可以使用Carthage來安裝。

在創建的Cartfile文件中添加:

github "facebook/FBMemoryProfiler"

之后,運行carthage update --configuration Debug即可。

因為我的app要從iOS6開始支持,所以我沒有使用這個。

嵌入代碼

首先,要在main.m中添加FBRetainCycleDetector的hook,同時,也要開啟FBAllocationTracker的生成追蹤:

#import <UIKit/UIKit.h>#import "AppDelegate.h"#if DEBUG#import <FBAllocationTracker/FBAllocationTrackerManager.h>#import <FBRetainCycleDetector/FBRetainCycleDetector.h>#endifint main(int argc, char * argv[]) {    @autoreleasepool {#if DEBUG        [FBAssociationManager hook];        [[FBAllocationTrackerManager sharedManager] startTrackingAllocations];        [[FBAllocationTrackerManager sharedManager] enableGenerations];#endif        return UIapplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));    }}

我習慣于添加一個DEBUG標識符,只在Debug狀態才開啟FBMemoryProfiler。當然,你可以不需要。

之后,我們要在AppDelegate.mapplication: didFinishLaunchingWithOptions:中嵌入FBMemoryProfiler的創建代碼:

#if DEBUG#import <FBMemoryProfiler/FBMemoryProfiler.h>#import <FBRetainCycleDetector/FBRetainCycleDetector.h>#import "CacheCleanerPlugin.h"#import "RetainCycleLoggerPlugin.h"#endif@interface AppDelegate (){#if DEBUG    FBMemoryProfiler *memoryProfiler;#endif}@end@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {#if DEBUG    memoryProfiler = [[FBMemoryProfiler alloc] initWithPlugins:@[[CacheCleanerPlugin new],                                                                  [RetainCycleLoggerPlugin new]]                              retainCycleDetectorConfiguration:nil];    [memoryProfiler enable];#endif    return YES;}@end

其中,插件是可以不開啟的,如果你不想開啟的話,你可以這么寫:

FBMemoryProfiler *memoryProfiler = [FBMemoryProfiler new];[memoryProfiler enable];

插件主要是用來進行過濾、去重或者輸出、存儲等操作的,畢竟如果不開啟插件的話,只能通過在手機、模擬器上點擊屏幕來看內存泄露,而如果自定義log插件的話,可以將捕獲到的內存泄露輸出到控制臺或者文件中。

比如說,我們可以自定義一個RetainCycleLoggerPlugin,使用FBMemoryProfilerPluggable協議,重寫memoryProfilerDidFindRetainCycles:方法:

- (void)memoryProfilerDidFindRetainCycles:(NSSet *)retainCycles{    if (retainCycles.count > 0)    {        NSLog(@"/nretainCycles = /n%@", retainCycles);    }}

FBRetainCycleDetector找到循環引用之后,就會調用到上面的方法,但是,retainCycles可能是個空集合,所以這里可以過濾一下。

我在測試我的app的時候,發現這樣一個問題:

我確信這里沒有因為我而導致的循環引用,但是FBRetainCycleDetector在這里檢測到了這個環,這里的主要問題在于_subviewCache,這是蘋果的機制,但是并不會造成內存泄露。對于這種情況,我們需要將它過濾出去。

除此之外,還有一個Timer的問題,因為一般情況下,Timer會強引用target,所以可能導致內存泄露,如果你確信沒有問題的話,可以關閉對Timer的檢測。

過濾代碼類似于這種:

NSArray *filters = @[FBFilterBlockWithObjectIvarRelation([UIView class], @"_subviewCache")];FBObjectGraphConfiguration *configuration =[[FBObjectGraphConfiguration alloc] initWithFilterBlocks:filters                                     shouldInspectTimers:YES];memoryProfiler = [[FBMemoryProfiler alloc] initWithPlugins:@[[CacheCleanerPlugin new],                                                                  [RetainCycleLoggerPlugin new]]                               retainCycleDetectorConfiguration:configuration];[memoryProfiler enable];

我們只需要設置一個過濾數組,然后添加到FBMemoryProfilerConfiguration中即可。

對于你確信沒有問題或者不想修改的問題,你可以在Configuration中直接過濾掉。

比如:

NSArray *filters = @[FBFilterBlockWithObjectIvarRelation([UipanGestureRecognizer class], @"_internalActiveTouches")];

如果你有CI的需要,你可以在代理中輸出log到文本,之后傳出到服務器上。

運行

具體操作可以參考Facebook的視頻,上一篇譯文中也有給出。


上一篇:沉浸式模式


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 克拉玛依市| 藁城市| 社旗县| 宁陕县| 师宗县| 惠水县| 保康县| 云林县| 玉环县| 宜黄县| 镇康县| 府谷县| 满城县| 启东市| 山西省| 六枝特区| 舞阳县| 韶山市| 营口市| 沾益县| 沽源县| 扶绥县| 思茅市| 巴里| 沭阳县| 宣威市| 阳春市| 扬州市| 湖北省| 博爱县| 黄平县| 安龙县| 仁怀市| 颍上县| 凌海市| 灵宝市| 宣恩县| 宁都县| 巩义市| 清流县| 寿宁县|