我有一个使用多个模态表进行数据输入的应用。打开模态表的方法运行良好,仍然可以正常工作,但它们已经被弃用了,我担心它们很快就不能用于未来的Xcode版本。 Here, Apple points out how to use modal sheets,
- (void)showCustomSheet: (NSWindow *)window
// User has asked to see the custom display. Display it.
{
if (!myCustomSheet)
//Check the myCustomSheet instance variable to make sure the custom sheet does not already exist.
[NSBundle loadNibNamed: @"MyCustomSheet" owner: self];
[NSApp beginSheet: myCustomSheet
modalForWindow: window
modalDelegate: self
didEndSelector: @selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
// Sheet is up here.
// Return processing to the event loop
}
但随着Xcode 5.1的发布,他们发现loadNibNamed方法已被弃用,我们应该使用引用顶级对象的类似函数。
我遇到的问题正在改变这个:
[NSBundle loadNibNamed:@"OrderDetailsWindow" owner:self];
进入这个。
NSArray *array;
[[NSBundle mainBundle]loadNibNamed:@"OrderDetailsWindow" owner:self topLevelObjects:&array];
此方法调用确实打开了模态表。但是,在打开模式表的方法结束时,Xcode会挂起此错误。
0x7fff8c33b097: andl 24(%r11), %r10d Thread1: EXC_BAD_ACCESS (code:EXC_I386_GPFLT)
我不确定这是告诉我的。它没有在调试区域中提供任何信息。这可能与topLevelObjects数组没有正确发布有关吗?关于如何使这项工作更顺利的任何想法?苹果公司过时的图书馆让我疯狂!
答案 0 :(得分:4)
是的,Apple的文档很乱。自2009年以来,“工作表编程主题”文档尚未更新。
更改后你没有显示完整的代码,但我的猜测是你的问题在于NIB对象的内存管理。
来自新loadNibNamed:owner:topLevelObjects:
与传统方法不同,对象遵循标准的可可内存 管理规则;有必要对它们进行有力的参考 通过使用IBOutlets或持有对数组的引用来防止 nib内容被解除分配。
顶级对象的出口应该是强引用 证明所有权并防止重新分配。
您拥有保存方法中顶级对象的NSArray。一旦执行离开这个方法,NSArray就会被删除并释放,如果那些在其他任何地方都没有被强烈引用,那么你的所有顶级对象也是如此。
您需要将NIB中的顶级对象连接到Window Controller中的出口,或者将NSArray保留为Window Controller实例的成员变量,因此一旦表单显示方法退出,它就不会被释放。并确保myCustomSheet正确声明并从工作表的NIB连接。
此外,[NSApp beginSheet:]
也已弃用,现在请致电beginSheet on an instance of NSWindow。
答案 1 :(得分:0)
我总是使用NSWindowController
子类和我的工作表的自定义委托:
从想要显示工作表的窗口中:
_myModalController = [[MyModalController alloc] init];
_myModalController.delegate = self;
[_myModalController beginSheet:self.window];
然后在模态窗口控制器中,我有:
- (id)init {
self = [super initWithWindowNibName:@"MyModalWindow" owner:self];
return self;
}
- (void)beginSheet:(NSWindow *)mainWindow {
[NSApp beginSheet:[self window]
modalForWindow:mainWindow
modalDelegate:self
didEndSelector:@selector(_didEndSheet:returnCode:contextInfo:)
contextInfo:nil];
}
- (void)endSheet:(NSWindow *)mainWindow {
[NSApp endSheet:[self window]];
[[self window] orderOut:mainWindow];
}
这似乎可以避免loadNibNamed:
被弃用的整个问题。