使用beginSheetModalForWindow的NSAlert错误

时间:2012-05-17 08:53:52

标签: objective-c

ABTRACT: 当方法beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo contextInfo 提供NSArray或NSDictionary的对象时,它实际上将成为指向内存中任何位置的任意指针。对此有什么合适的解决方案?

以下说明了问题:

- (IBAction)testbutton:(id)sender {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert beginSheetModalForWindow:theWindow
                      modalDelegate:self 
                      idEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) 
                        contextInfo:[NSArray arrayWithObject:@"bla bla"]];

}

- (void) alertDidEnd:(NSAlert *)alert 
          returnCode:(NSInteger)returnCode 
         contextInfo:(NSArray *)contextInfo {
    NSLog(@"contextInfo: %@", contextInfo);

}

NSLog将在内存中输出任意内容,包括指针为空时崩溃。 但是,如果contextInfo更简单,例如NSString,NSNumber,甚至是诸如NSTextField之类的插座,它都可以正常工作。另外,如果我提供的是NSArray或NSDictionary的实例变量,那么它可以工作。

在Apples文档中, contextInfo 被声明为(void *),因此它可以是任何东西(甚至是任意指针)。但是因为我知道了这个类,所以我在这个例子中声明它是NSArray。但问题不在于我声明contextInfo是什么。

当我有垃圾收集时,Lion会出现问题。

在消息Using NSAlert beginSheetModalForWindow with contextInfo'noa'中说“如果你正在使用垃圾收集,存储在一个实例变量中 - 任何地方都无关紧要 - 所以它不会在最后发布运行循环。你需要坚持下去,直到didEndSelector可以对其进行操作。“

这是一个很好的解决方法,但它很奇怪,而且非常难看。还没有更优雅的解决方案吗?

这种行为真的是Apple的意图吗?还是一个明确的错误?像NSString和NSNumber这样的简单对象是可以的,但不是NSArray。如果它确实不是一个bug,那么不应该指定contextInfo的限制,并且不应该准确地指定何时以及如何以某种方式明确保留它?或者除非 contextInfo 是一个实例变量,否则GC不会保证使用此方法做任何事情?

0 个答案:

没有答案