我有一个ObjC类(Writer),它具有一些属性,并在主线程上将这些属性写入。然后有其他类(Reader)在主线程或后台线程上读取这些属性。
当读者从主线程读取时,它得到的是Writer类中这些属性确切的值,但当读者从后台线程读取时,显然没有保证读者会得到相同的值。以下是示例代码:
在Writer类中: - numberString是由逗号分隔的全部为1的字符串,例如1,1,1,1 - numberSum是这些1的总和,例如4
在Reader类中: 我想确保numberSum确实是numberString变量中所有1的总和。
当读者从主线程读取时,它得到的是Writer类中这些属性确切的值,但当读者从后台线程读取时,显然没有保证读者会得到相同的值。以下是示例代码:
在Writer类中: - numberString是由逗号分隔的全部为1的字符串,例如1,1,1,1 - numberSum是这些1的总和,例如4
在Reader类中: 我想确保numberSum确实是numberString变量中所有1的总和。
// Writer Class
@interface Writer : NSObject
@property (nonatomic,strong) NSString* numberString;
@property (nonatomic,assign) NSUInteger numberSum;
@end
@implementation Writer
-(instancetype)init {
if (self = [super init]){
self.numberString = @"1";
self.numberSum = 1;
self.timer = [NSTimer timerWithTimeInterval:0.1f target:self selector:@selector(writeToVariables:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
return self;
}
- (void)writeToVariables:(NSTimer *)timer {
self.numberString = [self.numberString stringByAppendingString:@",1"];
self.numberSum += 1;
}
// Reader Class
@interface Reader ()
@property (nonatomic,strong) Writer* writer;
@end
@implementation Reader
-(instancetype)init {
if (self = [super init]){
self.writer = [Writer new];
}
return self;
}
-(void) getVariablesOnBackground:(BOOL)background {
void (^readerBlock)() = ^{
NSString* numberStr = self.writer.numberString;
// Introduce delay So background thread get time to update numberSum
int i=0;
while (i < 10000000) {
i += 1;
}
NSUInteger numberSum = self.writer.numberSum;
NSArray *onesArray = [numberStr componentsSeparatedByString:@","];
NSLog(@"%lu",(unsigned long)onesArray.count);
NSLog(@"%lu",(unsigned long)numberSum);
};
// If background then dispatch on default queue else just call the block
if (background) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),readerBlock);
}
else {
readerBlock();
}
}
@end
以下是示例代码,仅供参考。在readerBlock中的两个NSLog语句在主线程执行时始终相同,但在后台线程中它们有时会不同,因为在读取numberString后,在Reader中读取numberSum时,它已经被Writer中的主线程更新。
我该怎么做才能确保无论调用线程如何,都能获得正确的值?