关于Objective C:以编程方式更改可可粉绑定值

Changing cocoa bindings value programmatically

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

enter image description here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
- (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"];,则绑定工作正常,但如果添加项目失败,它也不会取消选中。

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


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

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