Если кому-то интересно, вот еще один макрос для того же самого :)
IMHO, он обеспечивает большую гибкость по сравнению с другими вариантами.
#define SHARED_INSTANCE(...) ({\
static dispatch_once_t pred;\
static id sharedObject;\
dispatch_once(&pred, ^{\
sharedObject = (__VA_ARGS__);\
});\
sharedObject;\
})
Использование, однострочная инициализация:
+ (instancetype) sharedInstanceOneLine {
return SHARED_INSTANCE( [[self alloc] init] );
}
Использование, многострочная инициализация (обратите внимание на фигурные скобки вокруг блока кода):
+ (instancetype) sharedInstanceMultiLine {
return SHARED_INSTANCE({
NSLog(@"creating shared instance");
CGFloat someValue = 84 / 2.0f;
[[self alloc] initWithSomeValue:someValue]; // no return statement
});
}
Использование в правой части задания:
- (void) someMethod {
MethodPrivateHelper *helper = SHARED_INSTANCE( [[MethodPrivateHelper alloc] init] );
// do smth with the helper
}
// someMethod should not call itself to avoid deadlock, see bbum's answer
Эта модификация использует две языковые функции: составные выражения GCC. расширение, которое также поддерживается Clang, и поддержка макросов C99 .
После предварительной обработки результат будет выглядеть так (вы можете проверить это самостоятельно, вызвав Product > Perform Action > Preprocess "YourClassName.m" в Xcode 5):
+ (instancetype) sharedInstanceOneLine {
return ({
static dispatch_once_t pred;
static id sharedObject;
dispatch_once(&pred, ^{
sharedObject = ( [[self alloc] init] );
});
sharedObject; // this object will be returned from the block
});
}
+ (instancetype) sharedInstanceMultiLine {
return ({
static dispatch_once_t pred;
static id sharedObject;
dispatch_once(&pred, ^{
sharedObject = ({
NSLog(@"creating shared instance");
CGFloat someValue = 84 / 2.0f;
[[self alloc] initWithSomeValue:someValue];
});
});
sharedObject;
});
}
- (void) someMethod {
MethodPrivateHelper *helper = ({
static dispatch_once_t pred;
static id sharedObject;
dispatch_once(&pred, ^{
sharedObject = ( [[MethodPrivateHelper alloc] init] );
});
sharedObject;
});
}
person
skozin
schedule
08.01.2014