【问题标题】:Using static keyword in objective-c when defining a cached variable定义缓存变量时在objective-c中使用static关键字
【发布时间】:2009-02-16 23:10:59
【问题描述】:

我正在查看以下苹果示例源代码:

    /*
 Cache the formatter. Normally you would use one of the date formatter styles (such as NSDateFormatterShortStyle), but here we want a specific format that excludes seconds.
 */
static NSDateFormatter *dateFormatter = nil;
if (dateFormatter == nil) {
    dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"h:mm a"];
}

试图弄清楚:

  • 为什么要使用 static 关键字?

  • 如果每次调用方法时将其设置为 nil,这如何等同于缓存变量。

代码来自Tableview Suite demo中的示例4

【问题讨论】:

    标签: objective-c caching static


    【解决方案1】:

    静态变量在重复调用函数时保留其分配的值。它们基本上就像只对该函数“可见”的全局值。

    初始化语句只执行一次。

    此代码在第一次使用该函数时将 dateFormatter 初始化为 nil。在随后对该函数的每次调用中,都会对 dateFormatter 的值进行检查。如果未设置(仅在第一次为真),则会创建一个新的 dateFormatter。如果已设置,则将使用静态 dateFormatter 变量。

    熟悉静态变量是值得的。它们可能非常方便,但也有缺点(例如,在此示例中,无法释放 dateFormatter 对象)。

    提示:有时在代码中放置断点并查看发生了什么可能会很有教育意义。随着程序复杂性的增加,这将成为一项非常宝贵的技能。

    【讨论】:

    • 嗨@Andrew Grant,很好的解释,在这种情况下,正如你所提到的,不可能释放它,假设我想释放它并为日期格式化程序分配一个新值,然后应该怎么做。
    【解决方案2】:

    static”在这种情况下,在功能上意味着“不要每次都计算等号右侧的内容,而是使用它之前的值”。

    以重大责任使用这种强大的力量:您冒着使用大量内存的风险,因为这些是永远不会消失的对象。除了NSDateFormatter 这样的情况外,它很少适用。

    【讨论】:

    • 我知道这是个老问题,但想知道这个静态关键字对 ARC 的影响?
    • @codejunkie 静态数据存储在与堆不同的位置。 ARC 涉及保留和释放堆内存,以便值可以在堆栈帧之外持续存在。因此,我怀疑 ARC 对静态变量有任何影响。
    【解决方案3】:

    出于参考目的,这就是我在表格视图控制器中使用静态日期格式化程序的方式。

    + (NSDateFormatter *) relativeDateFormatter
    {
         static NSDateFormatter *dateFormatter;
         static dispatch_once_t onceToken;
         dispatch_once(&onceToken, ^{
             //NSLog(@"Created");
             dateFormatter = [[NSDateFormatter alloc] init];
             [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
             [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
             NSLocale *locale = [NSLocale currentLocale];
             [dateFormatter setLocale:locale];
             [dateFormatter setDoesRelativeDateFormatting:YES];
         });
         return dateFormatter;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      • 2012-07-08
      相关资源
      最近更新 更多