0

我的偏好中有一个NSButton可以与将应用程序添加到 LoginItems 进行交互。如果添加登录项失败,我想取消选中该框,这样用户就不会误认为它已添加到登录项中。但是,这样做之后,当我再次单击复选框时,不会触发绑定。

在此处输入图像描述

- (void)addLoginItem:(BOOL)status
{
    NSURL *url = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:
                  @"Contents/Library/LoginItems/HelperApp.app"];

    // Registering helper app
    if (LSRegisterURL((__bridge CFURLRef)url, true) != noErr) {
        NSLog(@"LSRegisterURL failed!");
    }

    if (!SMLoginItemSetEnabled((__bridge CFStringRef)[[NSBundle mainBundle] bundleIdentifier], (status) ? true : false)) {
        NSLog(@"SMLoginItemSetEnabled failed!");
        [self willChangeValueForKey:@"startAtLogin"];
        [self.startAtLogin setValue:[NSNumber numberWithBool:[self automaticStartup]] forKey:@"state"];
        [self didChangeValueForKey:@"startAtLogin"];
    }
}

- (void)setAutomaticStartup:(BOOL)state
{
    NSLog(@"Set automatic startup: %d", state);
    if ([self respondsToSelector:@selector(addLoginItem:)]) {
        [self addLoginItem:state];
    }
}

- (BOOL)automaticStartup
{

    BOOL isEnabled  = NO;

    // the easy and sane method (SMJobCopyDictionary) can pose problems when sandboxed. -_-
    CFArrayRef cfJobDicts = SMCopyAllJobDictionaries(kSMDomainUserLaunchd);
    NSArray* jobDicts = CFBridgingRelease(cfJobDicts);

    if (jobDicts && [jobDicts count] > 0) {
        for (NSDictionary* job in jobDicts) {
            if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:[job objectForKey:@"Label"]]) {
                isEnabled = [[job objectForKey:@"OnDemand"] boolValue];
                break;
            }
        }
    }
    NSLog(@"Is Enabled: %d", isEnabled);
//    if (isEnabled != _enabled) {
    [self willChangeValueForKey:@"startupEnabled"];
        startupEnabled = isEnabled;
    [self didChangeValueForKey:@"startupEnabled"];
//    }

    return isEnabled;
}

我将复选框的数据绑定绑定到self.automaticStartup. 如果我删除该行[self.startAtLogin setValue:[NSNumber numberWithBool:[self automaticStartup]] forKey:@"state"];,则绑定工作正常,但如果添加项目失败,它不会取消选中。

如何以编程方式更改此绑定值,以便不忽略所有其他绑定事件?

4

1 回答 1

0

根据您的解释,您的绑定值为automaticStartup,但您发送willChangeValueForKey:的是startAtLogin。为了使绑定正常工作,您需要在某些时候提醒绑定变量的更改。但是,由于您正处于setAutomaticStartup:当时的状态,因此在这里这样做并不安全。

在这种情况下,我不会使用绑定来执行更改本身,我会考虑旧式IBAction机制,然后通过IBOutlet当您可以确认状态时手动设置复选框值。

于 2013-04-14T12:03:25.100 回答