清除方法中的静态变量

时间:2014-05-21 16:10:45

标签: ios objective-c ios7 static dispatch

在我的一个方法中,我使用的是dispatch_once,我为其创建了一个静态变量。该方法按预期工作,单独运行时单元测试成功通过。但是当我同时运行测试时,其中一个测试失败了,因为方法中的静态变量保持了值。

我的方法:

+ (NSString *)myMethod
{
    static NSString *dayOfTheWeek;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
       // Do something.

        dayOfTheWeek = @"Monday";

        if (!dayOfTheWeek)
        {
            dayOfTheWeek = @"Sunday";
        }
    });

    return dayOfTheWeek;
}

问题:

所以我有单元测试来测试"星期一"和另一个测试"星期日"的单元测试。如果我在XCODE上单独执行这两个测试,它们会通过,但是当我一起执行它们时,测试"星期日"失败,因为我的静态变量仍然保持值"星期一"。

有没有办法可以清除方法级静态变量仅用于测试目的?或者还有其他方法可以成功执行这两项测试吗?

3 个答案:

答案 0 :(得分:5)

条件逻辑几乎从不属于dispatch_once()块。如果某种逻辑在不同的执行中可能有所不同,那么每次执行程序时可能需要更频繁地重新评估一次。目前还不清楚逻辑是什么,但是如果它类似于什么?今天是什么?"那么,如果你的程序运行了多天会发生什么?

答案 1 :(得分:1)

问题在于您错误地设计了此方法。两个考虑因素:

(1)一旦意味着一次。你不能签一份半合同。此代码将在应用程序的整个生命周期内执行一次。无论你改变输入,是否创建这个类的新实例等等,你调用它的次数并不重要。

(2)您要做的是研究 memoization 的概念。这是当您将输入与输出匹配时进行耗时的计算。一个好的模型是一个可变的字典。当输入到达时,您将在字典中查找该输入。如果结果在那里,则返回;如果它不存在,执行计算,将结果放在那里,然后返回。这样,您就可以避免为每个可能的输入进行耗时的计算

答案 2 :(得分:0)

我认为myMethod需要重构可测试性。如下所示:

// NOT THREAD-SAFE
static NSString *dayOfTheWeek;
+ (void) myMethodSetValue(NSString* value)
{
    dayOfTheWeek = value;
}

+ (NSString*) myMethodGetValue()
{
    return dayOfTheWeek;
}

+ (NSString *)myMethod
{
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        myMethodSetValue(&dayOfTheWeek, @"Monday");
    });

    return myMethodGetValue();
}

测试1

myMethodSetValue(@"Monday");
...
test routine

的Test2

myMethodSetValue(@"Sunday");
...
test routine