Утечка памяти в GeneralBlock-56 при вызове loadRequest в UIWebView - PullRequest
4 голосов
/ 29 марта 2011

Я работаю над приложением IPad и профилирую его, используя инструменты в XCode 4. Я профилирую на самом устройстве.Установлена ​​iOS 4.3.

Инструменты говорят мне, что у меня есть утечки памяти, утечка объектов в основном GeneralBlock-56 и некоторые GeneralBlock-1024 / GeneralBlock-8192.Интересно то, что об этих утечках сообщается только тогда, когда я загружаю URL-адрес в UIWebView, встроенный в мое приложение.Если я закомментирую вызов loadRequest, эти утечки исчезнут.Такое поведение постоянно воспроизводимо.

Вызовы loadRequest () выглядят так:

[webPage loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://slashdot.org"]]];

Кстати, я не указываю никаких делегатов для этого UIWebView.Утечки не показывают никакой ответственной библиотеки / ответственного кадра, и в самом правом кадре нет расширенной детализации.

Я попытался поиграться с настройками NSURLCache, например:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

Это уменьшает некоторые утечки памяти GeneralBlock, но некоторые все еще остаются.Любое понимание этого поведения очень приветствуется ... спасибо!

Ответы [ 4 ]

2 голосов
/ 06 октября 2011

Это сообщение об ошибке, которое я отправил с помощью инструмента Apple Developer Bug Reporting. Похоже, это одна из серьезных проблем, вызывающих утечку памяти в моем случае.

Сводка: передача неправильно отформатированного NSURL в NSData dataWithContentsOfURL: вызывает утечку памяти в методе createCanonicalURL ().

Шаги для воспроизведения

В любом простом проекте поместите следующие строки в свой контроллер, например, в loadView: или viewDidLoad: method.:

NSURL* u = [NSURL URLWithString:@"http:/portalqa01:70/Images/Leading%20out%20of%20a%20Downturn%20-%20Article%20Illustration%20-%20Large_tcm137-38905.gif"];
    NSData* data = [NSData dataWithContentsOfURL:u options:0 error:nil];

Обратите внимание, что URL имеет только одну косую черту после "http:" вместо обычных двух.

Ожидаемые результаты: утечки памяти не должно быть.

Фактические результаты: приборы показывают утечку памяти.

регрессия: Это происходит только для некоторых некорректных URL-адресов, приведенный выше пример является конкретным примером. URL-адрес типа «http: /blah/blah.png» не вызовет утечку. Среды, используемые для воспроизведения этого были:

  • iPad 4.3 Simulator
  • iPad 2 с iOS 4.3.1

Примечания: Трассировка стека выглядит следующим образом:

STACK TRACE START

   0 CFNetwork createCanonicalURL
   1 CFNetwork HTTPProtocol::_createMutableCanonicalRequest(__CFAllocator const*, _CFURLRequest const*, void const*)
   2 CFNetwork HTTPProtocol::_createCanonicalRequest(__CFAllocator const*, _CFURLRequest const*, void const*)
   3 CFNetwork HTTPProtocol::copyCanonicalRequest()
   4 CFNetwork URLConnectionLoader::copyProtocolCanonicalRequest()
   5 CFNetwork URLConnectionClient::getRequestForTransmission(unsigned char, _CFURLResponse*, _CFURLRequest const*, __CFError**)
   6 CFNetwork URLConnectionClient::_clientWillSendRequest(_CFURLRequest const*, _CFURLResponse*, URLConnectionClient::ClientConnectionEventQueue*)
   7 CFNetwork URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload(XConnectionEventInfo<XClientEvent, XClientEventParams>*, long)
   8 CFNetwork URLConnectionClient::processEvents()
   9 CFNetwork MultiplexerSource::perform()
  10 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
  11 CoreFoundation __CFRunLoopDoSources0
  12 CoreFoundation __CFRunLoopRun
  13 CoreFoundation CFRunLoopRunSpecific
  14 CoreFoundation CFRunLoopRunInMode
  15 CFNetwork CFURLConnectionSendSynchronousRequest
  16 Foundation +[NSURLConnection sendSynchronousRequest:returningResponse:error:]
  17 Foundation -[NSData(NSData) initWithContentsOfURL:options:error:]
  18 Foundation +[NSData(NSData) dataWithContentsOfURL:options:error:]
  19 MemLeakTester -[MemLeakTesterViewController viewDidLoad] /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/MemLeakTesterViewController.m:36
  20 UIKit -[UIViewController view]
  21 UIKit -[UIWindow addRootViewControllerViewIfPossible]
  22 MemLeakTester -[MemLeakTesterAppDelegate application:didFinishLaunchingWithOptions:] /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/MemLeakTesterAppDelegate.m:27
  23 UIKit -[UIApplication _callInitializationDelegatesForURL:payload:suspended:]
  24 UIKit -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]
  25 UIKit -[UIApplication handleEvent:withNewEvent:]
  26 UIKit -[UIApplication sendEvent:]
  27 UIKit _UIApplicationHandleEvent
  28 GraphicsServices PurpleEventCallback
  29 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
  30 CoreFoundation __CFRunLoopDoSource1
  31 CoreFoundation __CFRunLoopRun
  32 CoreFoundation CFRunLoopRunSpecific
  33 CoreFoundation CFRunLoopRunInMode
  34 UIKit -[UIApplication _run]
  35 UIKit UIApplicationMain
  36 MemLeakTester main /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/main.m:14
  37 MemLeakTester start

STACK TRACE END

1 голос
/ 15 апреля 2011

Попробуйте добавить

[webView loadHTMLString: @"" baseURL: nil];

прямо перед выпуском веб-просмотра.Для утечки в 4.2.1, связанной с отображением PDF в UIWebView, это решает большинство проблем утечки для меня.

1 голос
/ 26 июля 2011

Ну, у меня была та же проблема с UIWebView - целая куча утечек (General-Block56 и т. Д.) На iPad, iPad2, iPhone.Наконец, помогло следующее: отклонить Nib-файл и метод 'viewDidLoad'.Вместо этого я программно создал веб-просмотр в 'loadView':

- (void)loadView 
{ 
    self.activityView = [[[UIActivityIndicatorView alloc]    initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
    self.webView = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    [self.webView addSubview: self.activityView];
    self.webView.scalesPageToFit = YES;
    self.view = self.webView;
    [self addGestures];
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
      self.webView.delegate = self;
      [self.webView loadRequest:[self urlRequest]];
      [super viewWillAppear:animated];

}

В конце осталась только одна небольшая утечка (16 байт) сразу после начала загрузки самой первой страницы.Все остальные страницы загрузились без каких-либо утечек.Надеюсь это поможет.

1 голос
/ 02 апреля 2011

У меня такая же проблема. Я все еще пытаюсь это проверить, но мое первоначальное наблюдение состоит в том, что это происходит только с сайтами, которые обслуживают JavaScript. Вы наблюдали эту картину?

...