Ответ 1
Прежде всего, я должен отметить, что это нехорошо делать в любой ситуации, кроме тестирования; даже тогда, продолжайте с осторожностью - AliSoftware предоставляет некоторые детали и пример кода в комментариях ниже. См. Также интересные ответы в Могу ли я объявить предикат dispatch_once_t
как переменную-член вместо статики?, включая важную информацию от устья лошади.
dispatch_once_t
является typedef
d long
. Его ложное значение равно 0. Если вы reset, флаг которого равен 0, dispatch_once()
снова запустится. Ваша проблема "просто", как изменить значение статической переменной из другого модуля компиляции. Для этого я думаю, что вам нужен отладочный /unit test hook, например:
MakeWhoopie.h
#import <Foundation/Foundation.h>
void makeWhoopie(void);
#ifdef DEBUG
void resetDispatchOnce(void);
#endif
MakeWhoopie.m
#include "MakeWhoopie.h"
static dispatch_once_t * once_token_debug;
void makeWhoopie(void)
{
static dispatch_once_t once_token;
once_token_debug = &once_token; // Store address of once_token
// to access it in debug function.
dispatch_once(&once_token, ^{
NSLog(@"That what you get, folks.");
});
NSLog(@"Making whoopie.");
}
#ifdef DEBUG
void resetDispatchOnce(void)
{
*once_token_debug = 0;
}
#endif
(Вы также можете переместить once_token
до уровня файла и изменить его напрямую.)
Попытка:
#import <Foundation/Foundation.h>
#import "MakeWhoopie.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
makeWhoopie();
makeWhoopie();
resetDispatchOnce();
makeWhoopie();
}
return 0;
}
Результаты в:
2012-06-07 18: 45: 28.134 ResetDispatchOnce [8628: 403] Что вы получаете, ребята.
2012-06-07 18: 45: 28.163 ResetDispatchOnce [8628: 403] Создание whoopie.
2012-06-07 18: 45: 28.164 ResetDispatchOnce [8628: 403] Создание whoopie.
2012-06-07 18: 45: 28.165 ResetDispatchOnce [8628: 403] Это то, что вы получаете, ребята.
2012-06-07 18: 45: 28.165 ResetDispatchOnce [8628: 403] Создание воинственности.