NSMenuItem追加時にエラーが発生する場合の対処

NSMenuItem周りのエラーです。

2015-08-24 00:00:00.272 McLab[71290:303] *** Assertion failure in -[NSMenu insertItem:atIndex:], /SourceCache/AppKit/AppKit-1265.20/Menus.subproj/NSMenu.m:635
2015-08-24 00:00:00.272 McLab[71290:303] An uncaught exception was raised
2015-08-24 00:00:00.273 McLab[71290:303] item to be inserted into menu already is in another menu
2015-08-24 00:00:00.275 McLab[71290:303] (
	0   CoreFoundation                      0x00007fff8663b25c __exceptionPreprocess + 172
	1   libobjc.A.dylib                     0x00007fff8cdf8e75 objc_exception_throw + 43
	2   CoreFoundation                      0x00007fff8663b038 +[NSException raise:format:arguments:] + 104
	3   Foundation                          0x00007fff85f48d41 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 189
	4   AppKit                              0x00007fff8d469999 -[NSMenu insertItem:atIndex:] + 288
	5   McLab                               0x00000001000436e5 -[MyController menuWillOpen:] + 565
	6   AppKit                              0x00007fff8d9e8687 -[NSMenu _sendMenuOpeningNotification] + 99
	7   AppKit                              0x00007fff8d85d326 -[NSCarbonMenuImpl _carbonOpenEvent:handlerCallRef:] + 28
	...
)

既にNSMenuに登録されているNSMenuItemを別のNSMenuに追加しようとしていることが原因です。

エラーパターンと対応策

既に追加済みのNSMenuItemを他のNSMenuに追加する場合は、先に対象アイテムを既存NSMenuから削除します。 removeItem:メソッド等を使うと良いでしょう。

// Errorパターン
[menuA addItem:_menuItem];
[menuB addItem:_menuItem];

// 対応策
[menuA removeItem:_menuItem];
[menuB addItem:_menuItem];

また、NSMenuのsubmenu追加時にも同様のエラーが発生することがあります。 submenu(NSMenu)内のNSMenuItemが既に他のNSMenuに追加されている可能性があるためです。

// Errorパターン
menuA.submenu = _submenu;
menuB.submenu = _submenu;

// 正常パターン
menuA.submenu = nil;
menuB.submenu = _submenu;

俺「フッ、全てお見通しってわけか…」
Objective-C「なに格好付けて開き直ってるんですか…」

広告