Утечка памяти с showWindow NSWindowController: - PullRequest
3 голосов
/ 25 мая 2011

Я уже некоторое время борюсь со следующей утечкой.Я сузил его с помощью Инструментов до следующего блока кода:

- (NewMessageWindowController *)showNewMessageWindowWithRecipients:(NSArray *)recipients {

    NewMessageWindowController * newMessageWindowController = [[NewMessageWindowController alloc] init];
    [newMessageWindowController showWindow:self]; // 100% on this line.
    [newMessageWindowController.toField setStringValue:[recipients componentsJoinedByString:@","]];
    [newMessageWindowController.messageView becomeFirstResponder];
    [windowControllers addObject:newMessageWindowController];
    [newMessageWindowController release];

    return newMessageWindowController;
}

Блок называется так:

[AppDelegate showNewMessageWindowWithRecipients:[NSArray arrayWithObject:recipient]];

Где recipient это просто строка NSString.

А вот обратный след от инструментов:

  30 Friendz start
  29 AppKit NSApplicationMain
  28 AppKit -[NSApplication run]
  27 AppKit -[NSApplication sendEvent:]
  26 AppKit -[NSWindow sendEvent:]
  25 AppKit -[NSWindow keyDown:]
  24 AppKit forwardMethod
  23 Friendz -[FriendzAppDelegate showNewMessageWindowWithRecipients:] /Path/To/FriendzAppDelegate.m:226
  22 AppKit -[NSWindowController showWindow:]
  21 AppKit -[NSWindow makeKeyAndOrderFront:]
  20 AppKit -[NSWindow _makeKeyRegardlessOfVisibility]
  19 AppKit -[NSWindow _changeKeyAndMainLimitedOK:]
  18 AppKit -[NSWindow becomeKeyWindow]
  17 AppKit _NXResetCursorState
  16 AppKit +[NSEvent _discardCursorEventsForWindowNumber:criteria:]
  15 HIToolbox FlushSpecificEventsFromQueue
  14 HIToolbox PullEventsFromWindowServer
  13 HIToolbox PullEventsFromWindowServerOnConnection(unsigned int, unsigned char)
  12 HIToolbox ConvertPlatformEventRecordAndPostWithOptions(__CGEvent*, _CGSEventRecord const*, short, unsigned char, unsigned char)
  11 HIToolbox PostEventToQueueInternal
  10 HIToolbox _NotifyEventLoopObservers
   9 HIToolbox KeyEventPostedObserver
   8 HIToolbox TSMProcessRawKeyCode
   7 HIToolbox TSMTranslateKeyEvent
   6 HIToolbox GetDataFromUCHRForEvent
   5 HIToolbox ConvertEventUniCharsToCharCodes
   4 HIToolbox utGetInputSourceScriptInfo
   3 CoreFoundation CFLocaleCreateCanonicalLocaleIdentifierFromScriptManagerCodes
   2 CoreFoundation CFStringCreateWithCStringNoCopy
   1 CoreFoundation __CFStringCreateImmutableFunnel3
   0 CoreFoundation _CFRuntimeCreateInstance

windowControllers - это NSMutableArray alloc / init'ed в applicationDidFinishLaunching и выпущенный в методе dealloc.

В NewMessageWindowController я использую следующее, чтобы уведомить делегата приложения о том, что окно закрывается, и больше нет необходимости удерживать контроллер:

- (void)windowWillClose:(NSNotification *)notification {
    [AppDelegate windowControllerDidFinish:self];
}

Метод делегата приложениявыглядит так:

- (void)windowControllerDidFinish:(NSWindowController *)controller {
    [windowControllers removeObject:controller];
}

Регистрация массива до и после - вот как я ожидаю.Контроллер находится там до закрытия окна, он удаляется при закрытии окна.

Прибор обнаруживает утечку, когда я закрываю окно.Пока он открыт, кажется, все в порядке.Стоит отметить, что dealloc вызывается в NewMessageWindowController, как и ожидалось.Утечки не сообщают о самом контроллере как о проблеме, вместо этого объект, который протекает, является NSCFString, он просто исходит из приведенного выше кода.почти уверен, что у меня все в порядке с памятью в блоке кода, который создает / показывает контроллер окна / окно.

Что странно, есть утечка, если я использую клавиатуру, чтобы закрыть окно.Если я нажму на красную кнопку закрытия, Instruments ничего не подберет.

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

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 25 мая 2011

Это потому, что вы не можете рассчитывать на то, что dealloc будет надежно вызываться, когда объект «уничтожен» - возможно, использование клавиатуры по какой-либо причине с меньшей вероятностью приведет к немедленному вызову dealloc, чем к нажатию X

0 голосов
/ 25 мая 2011

Что бы я сделал в этом случае, используя версию Instruments в Xcode4, сконфигурируйте инструмент распределения для записи событий сохранения / выпуска.Это должно показать вам, для этого конкретного контроллера, почему его счетчик отсчетов не стремится к нулю.Обратите внимание, что для закрытия на основе мыши и клавиатуры может быть другой кодовый путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...