簡體   English   中英

iOS 8.x + AFNetworking內存增長

[英]iOS 8.x + AFNetworking memory growth

我有一個應用程序長時間保持打開狀態,使用AFNetworking 2.5.0定期向我們的服務器調用API。 在iOS 8.x上,我看到每次API調用都會永久性地增加內存,最終導致內存不足崩潰。

我把我的所有代碼都煮掉了,只使用了AFNetworking(以及iOS下面的代碼),並且仍然看到了這種內存增長。 這是一個非常基本的例子,它將重現我所看到的內容:啟動應用程序並開始執行HTTP GET。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.manager = [AFHTTPRequestOperationManager manager];

    // Don't block out text/html extensions, for this example.
    _manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
    _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];

    [self getApiLoop];
    return YES;
}


- (void) getApiLoop {
    [_manager GET:@"http://www.stackoverflow.com" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"Success!");

        // Do it again
        dispatch_async(dispatch_get_main_queue(), ^{
            [self getApiLoop];
        });

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Failure!");

        // Do it again
        dispatch_async(dispatch_get_main_queue(), ^{
            [self getApiLoop];
        });

    }];
}

我在iOS 7.0上運行了相同的示例,並沒有看到同樣類型的失控內存增長。

儀器建議CFNetworking是malloc'ing而不是在下面釋放一些內存。

任何解決方法? 我們需要向Apple提交錯誤嗎?

我找到了一個適合我的代碼庫的解決方案,很高興分享它。

AFNetworking 2.x有2個入口點:

  • AFHTTPSessionManager.m - 推薦用於面向iOS 7和iOS 8的應用
  • AFHTTPRequestOperationManager.m - 推薦用於需要返回iOS 6的應用

我的應用程序需要iOS 6及更高版本,所以我從AFHTTPRequestOperationManager.m開始。 不幸的是,AFHTTPRequestOperationManager.m在iOS 8上出現內存問題,而AFHTTPSessionManager.m沒有(!) 不幸的是,這兩位經理的軟件API完全不同。

我的解決方案是在AFNetworking和我的應用程序的其余部分之間構建一個抽象層,這為我提供了兩個目的:一個適用於iOS 6的應用程序,不會在iOS 8上使用內存失控; 以及一個抽象層,它應該阻止我的團隊每次AFNetworking更改時都必須在我的應用程序中編輯每個API調用。

我的應用程序不一定需要訪問AFNetworking提供的全部功能,所以我只實現了我需要的功能:

  • initWithBaseURL
  • getResponseSerializer - (明確命名,所以我們不要混淆)
  • getRequestSerializer - (明確命名,所以我們不要混淆)
  • setResponseSerializer - (明確命名,所以我們不要混淆)
  • setRequestSerializer - (明確命名,所以我們不要混淆)
  • 使用setValue設置標頭:forHTTPHeaderField:
  • 得到
  • POST
  • 刪除
  • ......以及取消操作的能力

AFNetworking之上的抽象層的一個優點是開發人員可以有效地編輯應用於下面的AFNetworking的更改。 例如,當AFNetworking從1.x遷移到2.x時,每個人的應用程序都需要進行大量的代碼返工才能與新API保持一致。 使用抽象層,您可以選擇在一個阻塞點上翻譯新的AFNetworking API時保持應用程序的API一致,從而加快開發速度。

我在Apache 2.0許可下共享了我的代碼:

https://github.com/eemoss/afnetworking-abstractionlayer-ios

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM