我在一个应用程序中有以下代码(编写于2011年)。
[[[[NSApp delegate] myWindowController] ...] ..];
由于升级到Xcode 6.1,这会产生以下错误:-ARC Semantic Issue No known instance method for selector 'myWindowController'
将其替换为以下内容不会产生错误。
id ttt = [NSApp delegate];
[[[ttt myWindowController] ...] ...];
PS Xcode似乎认为类型是"id<NSFileManagerDelegate>'
这是怎么回事?
我承认我对Cocoa和Xcode非常生疏。我确信我可以通过合适的演员阵容来修复它,但这似乎没有必要,我正在努力理解为什么。
更多信息
我的AppDelegate.h
IBOutlet MyWindowController *myWindowController;
和AppDelegate.m
@synthesize myWindowController;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
myWindowController = [[MyWindowController alloc] initWithWindowNibName:@"MainWindow"];
我通过强制转换(MyAppDelegate *)
解决了这个问题。
[[[(MyAppDelegate *)[NSApp delegate] myWindowController] currentTvc] saveTableColumns]; // Xcode 6.1 error
我已经得出结论,这是一个Xcode 6.1错误,因为它似乎认为[NSApp delegate]
返回类型id<NSFileManagerDelegate>
- 请确保您正在导入包含MyWindowController@接口定义的标头
- 使用(MyWindowController*)投射您的[NSApp委派]
所以你原来的路线:
[[[[NSApp delegate] myWindowController] ...] ..];
应该变成:
[[[(MyAppDelegate *)[NSApp delegate] myWindowController] ...] ..];
您也可以使用(id)进行强制转换,这实际上就是您对ttt变量所做的操作,但这有点欺骗。在强制转换时使用正确的类将为您提供更好的编译器检查,并帮助Xcode提供准确的自动完成建议(这是在错误发生之前检测错误的好方法)。基本上,声明或强制转换为id的对象意味着它可以是任何类的对象,因此在任何类中定义的任何方法都将被视为有效。
我自己对Xcode 6.1也有同样的问题。我认为编译器在Xcode 6.1中发生了某种变化。我真希望我自己能找到原因的答案。它并没有给Xcode 6.1注入太多信心。