Привет всем,
У меня есть заставка с obj-c и какао. Под OsX 10.6.2 все работает нормально, кроме следующего.
В моей заставке у меня есть WebView с запущенным приложением. Когда я пытаюсь вызвать мое приложение target-c (заставку) через javascript, я получаю сообщение об ошибке, и происходит сбой заставки и панели системных настроек.
Системные настройки [86666]
*** Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException»
причина: '- [сток NSCFArray]: нераспознанный селектор отправлен на экземпляр 0x20049b1e0'
*** Вызов стека при первом броске: (
0 CoreFoundation 0x00007fff8123a444 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff81f130f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff812931c0 + [NSObject (NSObject) doesNotRecognizeSelector:] + 0
3 CoreFoundation 0x00007fff8120d08f пересылка + 751
4 CoreFoundation 0x00007fff812091d8 _CF_forwarding_prep_0 + 232
5 WebCore 0x00007fff847adee0 _ZN3JSC8 Привязки12ObjcInstance10virtualEndEv + 48
6 WebCore 0x00007fff8470d71d _ZN3JSC16RuntimeObjectImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE + 397
7 JavaScriptCore 0x00007fff80862b66 NK3JSC7JSValue3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE + 486
)
Я знаю, что это похоже на некоторую утечку памяти, но, как вы увидите в коде, у меня действительно почти нет выделенных объектов.
Это происходит только тогда, когда я запускаю скринсейвер с помощью кнопки «Тест» из системных настроек заставки.
Когда я запускаю заставку через терминал или запускается автоматически, то же действие (вызов obj-c из javascript) работает нормально.
Может быть, у кого-то есть идея, откуда может возникнуть ошибка. Вот некоторый код из реализации:
@implementation ScreensaverView
- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview {
self = [super initWithFrame:frame isPreview:isPreview];
if (self) {
[self setAnimationTimeInterval:-1];
[self setAutoresizesSubviews:YES];
// ::::::::::::::::::::::: Init stuff ::::::::::::::::::
// init
quitFlag = false;
previewMode = isPreview;
// find out the path the screensaver bundle
pMainBundle = [NSBundle bundleForClass:[self class]];
pBundlePath = [pMainBundle bundlePath];
// read Info.plist
infoDict = [pMainBundle infoDictionary];
}
return self;
}
- (void)startAnimation
{
[super startAnimation];
// combine: bundle path + filename for screensaver file
NSString *pathToScreensaver = [NSString stringWithString:pBundlePath];
NSString *valueScreensaverFile;
if(!previewMode)
{
valueScreensaverFile = [infoDict objectForKey:@"ScreensaverFile"];
}
else
{
valueScreensaverFile = [infoDict objectForKey:@"PreviewFile"];
}
// add filename to bundle path
pathToScreensaver = [pathToScreensaver stringByAppendingString:valueScreensaverFile];
// complete NSURL to the screensaver file
NSURL *screensaverUrl = [NSURL fileURLWithPath: pathToScreensaver];
webView = [WebView alloc];
[webView initWithFrame:[self frame]];
[webView setDrawsBackground:NO];
// delegation policy for interactive mode
[webView setPolicyDelegate: self];
[webView setUIDelegate:self];
// load screensaver
[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:screensaverUrl]];
scriptObject = [webView windowScriptObject];
[scriptObject setValue:self forKey:@"screensaver"];
[self addSubview:webView];
}
- (void)stopAnimation
{
[[webView mainFrame] stopLoading];
[webView removeFromSuperview];
[webView release];
[super stopAnimation];
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
{
if (selector == @selector(quitScreenSaver)) {
return NO;
}
if(selector == @selector(gotoUrl:) ){
return NO;
}
return YES;
}
+(NSString *)webScriptNameForSelector:(SEL)selector
{
if(selector == @selector(quitScreenSaver))
{
return @"quitNoOpen";
}
if(selector == @selector(gotoUrl:))
{
return @"openAndQuit";
}
return nil;
}
- (void) quitScreenSaver
{
quitFlag = true;
[super stopAnimation];
}
- (void) gotoUrl:(NSString *) destinationURL
{
if(destinationURL == NULL)
{
return;
}
NSString * path = destinationURL;
NSURL * fileURL = [NSURL URLWithString:path];
[[ NSWorkspace sharedWorkspace ] openURL:fileURL];
[self quitScreenSaver];
}
@end
Надеюсь, вам хватит кода, чтобы увидеть некоторые проблемы / решения.
Буду очень признателен за любые ответы.