Я работаю с классом Objective-C, который содержит статическую переменную, которая может быть сохранена, извлеченный или освобождаться в любое время:атомарность уровня класса Статические переменные
user.h
@interface User : NSObject
/// Returns the current user if set, nil if not
+ (User * _Nullable)currentUser;
/// Sets the current user
+ (void)setCurrentUser:(NSString * _Nonnull)name;
/// Removes the current user
+ (void)removeCurrentUser;
// Getters
/// Returns the user's name if set, nil if there is no user set
@property (nullable, nonatomic, strong, readonly) NSString *name;
@end
User.m
@interface User()
@property (nullable, nonatomic, strong, readwrite) NSString *name;
@end
@implementation User
#pragma mark - Static Variables
static User *currentUser;
#pragma mark - Static Object Setters and Getters
+ (User *)currentUser
{
return currentUser;
}
+ (void)setCurrentUser:(NSString * _Nonnull)name
{
currentUser = [[User alloc] initWithName:name];
}
+ (void)removeCurrentUser
{
currentUser = nil;
}
#pragma mark - init
- (instancetype)initWithName:(NSString * _Nonnull)name
{
self = [super init];
if (self) {
_name = name;
}
return self;
}
@end
Мой вопрос на атомарность этой статической переменной класса уровня. This question утверждает, что ivars strong, readwrite, nonatomic
по умолчанию, а атомарность определяется получателем и сеттером. Это относится также и к статическим переменным? Есть currentUser
неатомный по умолчанию? Чтобы сделать атомарным, мне пришлось бы обернуть мой геттер и сеттер в @synchronized(self) { ... }
блоках?
Будет ли '@synchronized (self)' работать из метода класса, а не с помощью метода экземпляра (поскольку «self» в основном относится к «классу», а не к экземпляру)? – NSGod
@NSGod Это будет работать в методе класса и в сочетании с использованием '@synchronized ([self class])' в методах экземпляра, весь доступ будет синхронизирован с любым методом класса/экземпляра. Существует один случай, когда это происходит, и если есть какие-либо функции C в файле .m, которые также получают доступ к переменной 'static'. – rmaddy
Он также терпит неудачу, если есть подклассы. Если '+ currentUser' вызывается как для этого класса, так и для его подкласса, тогда' self' будет представлять собой две разные вещи, и обращения не будут синхронизированы. Safest будет '@synchronized ([Пользовательский класс])' или явным блокировкой. –