#objective-c #cocoa
#objective-c #cocoa
Вопрос:
В моем подклассе NSWindowController значение [self window] равно нулю.
В моем файле nib ЕСТЬ связь между владельцем файла (моим подклассом) и видом окна.
Почему я получаю эту ошибку?
Он перестал работать, когда я реорганизовал класс владельца файла (подкласс NSWindowController). Я обновил его в конце, поэтому не понимаю, почему он перестал работать.
Сбой строки:
session = [NSApp beginModalSessionForWindow:[self window]];
2011-10-25 12:27:14.377 MyApp [13161:b0f] *** Assertion failure in -[CBApplication _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:didEndSelector:contextInfo:], /SourceCache/AppKit/AppKit-1138.23/AppKit.subproj/NSApplication.m:3861
2011-10-25 12:27:14.377 MyApp[13161:b0f] An uncaught exception was raised
2011-10-25 12:27:14.378 MyApp[13161:b0f] Modal session requires modal window
2011-10-25 12:27:14.380 MyApp[13161:b0f] (
0 CoreFoundation 0x92e01d87 __raiseError 231
1 libobjc.A.dylib 0x9317e149 objc_exception_throw 155
2 CoreFoundation 0x92d69619 [NSException raise:format:arguments:] 137
3 Foundation 0x9c41c36f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 116
4 AppKit 0x958a987d -[NSApplication _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:didEndSelector:contextInfo:] 725
5 AppKit 0x958a1973 -[NSApplication beginModalSessionForWindow:] 72
6 MyApp 0x00042ca3 -[CBWindowController showModal:] 131
7 MyApp 0x00023c46 -[CBDocument showLinkWindow:shouldLinkAndUpdate:selectedOnly:] 1174
8 MyApp 0x00023cb1 -[CBDocument linkAllRootItems:] 81
9 MyApp 0x0002a9b4 -[CBApplicationDelegate linkAllItems:] 100
10 CoreFoundation 0x92d57091 -[NSObject performSelector:withObject:] 65
11 AppKit 0x956e1cb3 -[NSApplication sendAction:to:from:] 232
12 AppKit 0x957d5caf -[NSMenuItem _corePerformAction] 536
13 AppKit 0x957d592c -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] 171
14 AppKit 0x957d4fb5 -[NSMenu _performActionWithHighlightingForItemAtIndex:sendAccessibilityNotification:] 79
15 AppKit 0x95aaddab -[NSMenu performActionForItemAtIndex:] 65
16 AppKit 0x95aaddde -[NSMenu _internalPerformActionForItemAtIndex:] 45
17 AppKit 0x95ab200f -[NSMenuItem _internalPerformActionThroughMenuIfPossible] 106
18 AppKit 0x9591ba10 -[NSCarbonMenuImpl _carbonCommandProcessEvent:handlerCallRef:] 172
19 AppKit 0x9574a916 NSSLMMenuEventHandler 452
20 HIToolbox 0x9b175920 _Z22_InvokeEventHandlerUPPP25OpaqueEventHandlerCallRefP14OpaqueEventRefPvPFlS0_S2_S3_E 36
21 HIToolbox 0x9aff1803 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec 1602
22 HIToolbox 0x9aff0c80 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec 482
23 HIToolbox 0x9b005aa9 SendEventToEventTarget 76
24 HIToolbox 0x9b175de4 _ZL18SendHICommandEventmPK9HICommandmmhPKvP20OpaqueEventTargetRefS5_PP14OpaqueEventRef 482
25 HIToolbox 0x9b175e4e SendMenuCommandWithContextAndModifiers 70
26 HIToolbox 0x9b1e0697 SendMenuItemSelectedEvent 275
27 HIToolbox 0x9b0423f9 _ZL19FinishMenuSelectionP13SelectionDataP10MenuResultS2_ 129
28 HIToolbox 0x9b1d1574 _ZL14MenuSelectCoreP8MenuData5PointdmPP13OpaqueMenuRefPt 608
29 HIToolbox 0x9b03a0b2 _HandleMenuSelection2 636
30 HIToolbox 0x9b039e31 _HandleMenuSelection 53
31 AppKit 0x95646356 _NSHandleCarbonMenuEvent 302
32 AppKit 0x955d662e _DPSNextEvent 2196
33 AppKit 0x955d58ab -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] 113
34 AppKit 0x955d1c22 -[NSApplication run] 911
35 AppKit 0x9586618a NSApplicationMain 1054
36 MyApp 0x000042f4 main 36
37 MyApp 0x00002e06 start 54
Как создается NSWindowController:
CBWindowController *windowController = [[subClass alloc] init];
[windowController setRanAsModal:YES];
[windowController setDelegate:self];
[windowController setRootDocument:[NSApp mainWindowDocument]];
[windowController loadWindow];
[windowController centerOnMainWindow:sender];
Комментарии:
1. Можете ли вы показать немного больше контекста, например, что такое self и как оно создается, что такое window и как оно назначается? Рефакторинг не изменяет никаких имен кончиков, которые вы закодировали (например, @»MyNibName»), так что, вероятно, в этом и заключается ваша проблема.
2. @jrturton Имя файла xib не должно изменяться. То, что я обновил в файле xib, — это класс владельца файла. По сути, я переработал класс имени владельца файла. Предполагается, что код должен работать в любом случае.
3. Хорошо, хотя некоторый контекст все равно был бы хорош. Мое второе предположение заключается в том, что вы не переподключили розетки после изменения класса владельца файла.
4. @jrturton Все мои 50 выходов уже подключены. вы хотите сказать, что я должен разорвать их и снова подключить? 🙁
5. 50!! Тогда только в крайнем случае! Может быть, только
window
один, или проверьте, на чтоwindow
указывает ваша строка кода выше.
Ответ №1:
[self window]
должен указывать на допустимый объект window. Судя по вашим комментариям, это не так.
Вы должны проверить и повторно подключить выход окна или, если такого выхода нет, убедиться, что в этой переменной содержится допустимый объект.
Автоматический рефакторинг, похоже, не улавливает все — поэтому поиск в вашем проекте старого имени, по-видимому, будет полезным упражнением после рефакторинга, чтобы предотвратить подобные проблемы в будущем.
Комментарии:
1. Действительно, как я уже писал вам в последнем комментарии, я снова подключил розетку. Однако он по-прежнему равен нулю. (Перетащил строку от владельца файла к компоненту Window и выбрал окно свойств)
2. И я не изменил объект Window в своем xib-файле. Единственное, что я изменил до сих пор, — это класс владельца файла (после рефакторинга).
3. Я нашел в Интернете эту зацепку: больше экземпляров одного и того же оконного контроллера.. Я с трудом в это верю, так как я не менял код, но как я могу проверить, много ли у меня экземпляров?
4. Как вы создаете оконный контроллер в первую очередь? Это объект в другом коде или вы создаете его в коде?
5. Я добавил код к вопросу. Пожалуйста, обратите внимание, что код работал раньше, и я его не менял.
Ответ №2:
Я готов поспорить, что вы неправильно его инициализируете. Вам нужно указать имя кончика при инициализации вашего класса, например:
CBWindowController *windowController =
[[subClass alloc] initWithWindowNibName:@"MyWindow" owner:nil];
А еще лучше, просто добавьте этот код в метод инициализации вашего оконного контроллера.
Редактировать: Кроме того, НЕ вызывайте loadWindow для вашего объекта, этот метод вызывается автоматически при доступе к окну, как указано в документации.
Комментарии:
1. Ты бы выиграл это пари… перейдите к концу темы комментариев к моему ответу 🙂