你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> FBMemoryProfiler基礎教程

FBMemoryProfiler基礎教程

編輯:IOS開發基礎

1460973837299411.jpg

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

在上一篇《在iOS上自動檢測內存洩露》中,Facebook講解了FBMemoryProfiler的核心原理。鑒於有人在評論裡問怎麼使用,我這裡就簡單介紹一下。

安裝

CocoaPods

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

pod 'FBMemoryProfiler'

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

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

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

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

blogimage_fb_1.jpg

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

Carthage

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

在創建的Cartfile文件中添加:

github "facebook/FBMemoryProfiler"

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

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

嵌入代碼

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

#import 
#import "AppDelegate.h"
#if DEBUG
#import 
#import 
#endif
int 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.m的application: didFinishLaunchingWithOptions:中嵌入FBMemoryProfiler的創建代碼:

#if DEBUG
#import 
#import 
#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的時候,發現這樣一個問題:

blogimage_fb_2.jpg

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

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

blogimage_fb_3.jpg

過濾代碼類似於這種:

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];

我們只需要設置一個過濾數組,然後添加到FBMemoryProfiler的Configuration中即可。

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

比如:

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

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

運行

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

代碼

上面說到的代碼放在了這個demo中:https://github.com/Forkong/FBMemoryProfilerDemo

git clone 之後需要 pod install 一下,才可以運行。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved