我创建了一个 Objective-C 单例类。我在该类上有一些属性,包括 BOOL
属性。由于某些奇怪的原因,我声明的 BOOL
变量在设置的范围之外将自身“重置”为 YES。
在 Singleton 类的 header 中,BOOL
是使用带有以下参数的 @property
声明的:
@property (nonatomic, assign, readonly) BOOL shouldCryptData;
在Singleton类的@interface
实现中,我重新定义了与readwrite
相同的属性(因为我需要它只对外部类读,但是读/写给我自己)。
@interface SingletonClassName ()
@property (nonatomic, assign, readwrite) BOOL shouldCryptData;
@end
BOOL
属性在单例类的初始化期间设置。我在其中一种 init 方法中这样设置它。有多个 init 方法指定数据是否应该被加密 - 这只是设置位置的一个示例。我的 init 方法中只有一个调用 super,所有其他方法都调用主 init。
- (id)init {
self = [super init];
if (self) {
// Brief setup code
[self setShouldCryptData:NO]; // Have also tried using dot-notation and without *self*
// I can confirm that the shouldCryptData property is NO (within the current scope) right after setting it in this method
}
return self;
}
现在,奇怪的是,当我尝试从任何其他方法访问 shouldCryptData
时,它总是返回 YES。为什么显式设置为NO后会返回YES?
我没有以任何奇怪的方式访问它,就像这样:
if (self.shouldCryptData == YES) // Outside of the init method, this is ALWAYS true
我知道我做错了什么,但我想不通。我觉得它与单例有关,但我不确定。似乎 Google 和 StackOverflow 都对此没有任何答案。有什么想法吗?
编辑
单例实现:
//-------- Header ---------------------//
@interface SingletonClassName : NSObject
+ (SingletonClassName *)sharedManager;
@end
//-------- Implementation ------------//
@implementation
+ (SingletonClassName *)sharedManager {
static SingletonClassName *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (sharedManager == nil) sharedManager = [[super allocWithZone:NULL] init];
});
return sharedManager;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self sharedManager];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
最佳答案
最简单的解释是,您并不是一个单例,而是在一个实例上设置该属性,然后在另一个实例上读取它。
尝试在设置和访问属性的所有方法中执行 NSLog(@"%p", self)
并确保它们完全相同。
添加:
这是我常用的单例逻辑:
+ (instancetype) sharedInstance {
static MyClass *singleton;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[self alloc] init];
});
return singleton;
}
在需要时调用[MyClass sharedInstance]
。
关于ios - Objective-C Singleton 中的变量被重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20894822/