Objective c 在基于视图的NSTableView中的NSTextFields之间共享NSDateFormatter?

Objective c 在基于视图的NSTableView中的NSTextFields之间共享NSDateFormatter?,objective-c,macos,nsdateformatter,nstableview,nstextfield,Objective C,Macos,Nsdateformatter,Nstableview,Nstextfield,我到处寻找这个问题的答案,但唉,我在这里。我知道创建NSDateFormatter对象的成本很高,我不想为表中的每个NSTextField实例化一个对象。我面临的问题是,我的表是基于视图的(而不是基于单元格的),当尝试连接日期格式化程序的共享实例时,我会收到黄色警告符号和以下消息: 不支持的配置:“文本字段单元格”的出口“格式化程序”- “表视图单元格”已连接到无效的“日期格式化程序” 目标(基于视图的表视图中的对象只能是 已连接到表视图的代理。) 该警告的问题在于:上面引用的“日期格式化程序”

我到处寻找这个问题的答案,但唉,我在这里。我知道创建
NSDateFormatter
对象的成本很高,我不想为表中的每个
NSTextField
实例化一个对象。我面临的问题是,我的表是基于视图的(而不是基于单元格的),当尝试连接日期格式化程序的共享实例时,我会收到黄色警告符号和以下消息:

不支持的配置:“文本字段单元格”的出口“格式化程序”- “表视图单元格”已连接到无效的“日期格式化程序” 目标(基于视图的表视图中的对象只能是 已连接到表视图的代理。)


该警告的问题在于:上面引用的“日期格式化程序”是“文件所有者”的属性,而“文件所有者”恰好也是
NSTableView
的委托。我是否遗漏了一些内容,或者我必须为表中每个与日期相关的文本字段创建格式化程序?

您不应该为每个与日期相关的文本字段创建格式化程序。使用Singleton可以解决此问题

将此代码添加到viewController

    + (NSDateFormatter *)sharedDateFormatter
    {

        NSLog(@"%s",__func__);
        static dispatch_once_t once;
        static NSDateFormatter * _sharedDateFormatter;

        dispatch_once(&once, ^{
            _sharedDateFormatter  = [[NSDateFormatter alloc] init];
        });
        return _sharedDateFormatter;


    }
,然后您可以访问NSDateFormatter实例,如下所示:

    [[self class] sharedDateFormatter],or ['Your ViewController class ' sharedDateFormatter]
您可以向与日期相关的textfield添加属性,调用此方法将NSDateFormatter实例设置为textfield:

    yourTextField.dateFormatter =  ['Your ViewController class ' sharedDateFormatter];
它只会创建一个NSDateFormatter实例,如果您不理解,请阅读以下内容:


您不应该为每个与日期相关的文本字段创建格式化程序。使用Singleton可以解决这个问题

将此代码添加到viewController

    + (NSDateFormatter *)sharedDateFormatter
    {

        NSLog(@"%s",__func__);
        static dispatch_once_t once;
        static NSDateFormatter * _sharedDateFormatter;

        dispatch_once(&once, ^{
            _sharedDateFormatter  = [[NSDateFormatter alloc] init];
        });
        return _sharedDateFormatter;


    }
,然后您可以访问NSDateFormatter实例,如下所示:

    [[self class] sharedDateFormatter],or ['Your ViewController class ' sharedDateFormatter]
您可以向与日期相关的textfield添加属性,调用此方法将NSDateFormatter实例设置为textfield:

    yourTextField.dateFormatter =  ['Your ViewController class ' sharedDateFormatter];
它只会创建一个NSDateFormatter实例,如果您不理解,请阅读以下内容:


您可以通过编程方式而不是在xib文件中附加共享格式化程序。在用于返回单元格视图的委托方法中,假设您的单元格类为
MyCellView
,并且
MyCellView
具有属性
theTextField
,并且该视图是从名为
MyCellView.xib
的xib文件加载的:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    MyCellView *result = [tableView makeViewWithIdentifier:@"MyCellView" owner:self];
    [result.theTextField setFormatter:[[self class] sharedFormatter]];
    return result;
}
然后您需要这个
sharedFormatter
方法。
sharedFormatter
方法将设置一个延迟初始化的单例。这是iOS和Mac OS X开发中非常常见的一种模式,如果您以前没有见过这种模式,那么这是一种很好的学习模式:

+ (NSFormatter *)sharedFormatter {
    static NSFormatter *formatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [[NSFormatter alloc] init];
        /* Set up the formatter's attributes here */
    });
    return formatter;
}

因此
sharedFormatter
最多初始化一次其静态
formatter
变量(第一次调用
sharedFormatter
方法)。
dispatch\u once
使其输入块中的所有代码只执行一次,甚至负责同步在多个线程上发生的调用(尽管我怀疑您是否会从多个线程调用
sharedFormatter

您可以通过编程方式附加共享格式化程序,而不是在xib文件中。在用于返回单元格视图的委托方法中,假设您的单元格类为
MyCellView
,并且
MyCellView
具有属性
theTextField
,并且该视图是从名为
MyCellView.xib
的xib文件加载的:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    MyCellView *result = [tableView makeViewWithIdentifier:@"MyCellView" owner:self];
    [result.theTextField setFormatter:[[self class] sharedFormatter]];
    return result;
}
然后您需要这个
sharedFormatter
方法。
sharedFormatter
方法将设置一个延迟初始化的单例。这是iOS和Mac OS X开发中非常常见的一种模式,如果您以前没有见过这种模式,那么这是一种很好的学习模式:

+ (NSFormatter *)sharedFormatter {
    static NSFormatter *formatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [[NSFormatter alloc] init];
        /* Set up the formatter's attributes here */
    });
    return formatter;
}

因此
sharedFormatter
最多初始化一次其静态
formatter
变量(第一次调用
sharedFormatter
方法)。
dispatch\u once
使其输入块中的所有代码只执行一次,甚至负责同步多个线程上发生的调用(尽管我怀疑您是否会从多个线程调用
sharedFormatter

感谢您的详细响应!事实上,这正是我在发布这篇文章后所做的。唯一的区别是,我使用的不是类方法,而是实例方法,没有
dispatch\u once
调用。我会用我最新的“问题”更新我上面的问题。把我刚才说的都记下来。成功了。我有一个日期格式问题。总是一些小事打破了一切。再次感谢。感谢您的详细回复!事实上,这正是我在发布这篇文章后所做的。唯一的区别是,我使用的不是类方法,而是实例方法,没有
dispatch\u once
调用。我会用我最新的“问题”更新我上面的问题。把我刚才说的都记下来。成功了。我有一个日期格式问题。总是一些小事打破了一切。再次感谢。也谢谢你的回复。我实现了类格式化程序,但仍然没有在单元格中获得输出。只是一片空白。有什么想法吗?请看我的最新问题,看看我在哪里。编辑:我想出来了。谢谢你的回复,也谢谢你的回复。我实现了类格式化程序,但仍然没有在单元格中获得输出。只是一片空白。有什么想法吗?请看我的最新问题,看看我在哪里。编辑:我想出来了。谢谢你的回复。