iOS - synchronized genlock applications and dispatch_barrier

 

 

 

synchronized lock synchronization, synchronization lock objects need to perform a synchronization after waiting for a lock on the execution is completed, and after the execution, the lock will release the contents synchronized code block. 

// the problem of low efficiency, to perform before and after the incoming object must wait for a lock executed, can not achieve asynchronous effect 
- ( void ) {synchronizedMethod 
    NSObject * obj = [[NSObject alloc] the init]; 
    dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^ { 
        @Synchronized (Self) { // lock Self 
            NSLog ( @ " synchronous operation start! " ); 
            SLEEP ( . 3 ); 
            NSLog ( @ " synchronization end! " ); 
       } 
    }); 
    dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT , 1 ), ^{ 
        SLEEP ( 2 ); 
        @Synchronized (obj) { // lock obj 
            NSLog ( @ " synchronous operation 2 " ); 
        } 
    }); 
}

 

GCD fence Application

In the queue, the fence block must be performed separately, not in parallel with other blocks.

And write readblock writeblock has the advantage of reusability and lower strong coupling, which can then initialize the other classes GCDAccessor a class method called directly read and write, read and write in different data block. A data corresponding to a GCDAccessor example.

But there is a parallel asynchronous problems.

 

//.h
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface GCDAccessor : NSObject
-(id)readWithGCD:(id(^)(void))readBlock;
-(void)writeWithGCD:(void(^)(void))writeBlock;
@end

NS_ASSUME_NONNULL_END


//.m

#import "GCDAccessor.h"

@interface GCDAccessor ()
@property(nonatomic,strong) dispatch_queue_t syncQueue;
@end


@implementation GCDAccessor
//串行同步队列
-(instancetype)init{
    self = [super init];
    if (self != nil) {
        _syncQueue = dispatch_queue_create("accessor", DISPATCH_QUEUE_CONCURRENT);
    }
    return self;
}

-(id)readWithGCD:(id(^)(void))readBlock{
    __block id readValue = nil;
    dispatch_sync(_syncQueue, ^{
        readValue = readBlock();
    });
    return readValue;
}

-(void)writeWithGCD:(void(^)(void))writeBlock{
    dispatch_barrier_async(_syncQueue, writeBlock);
}

 

Use:

@interface ViewController ()<WKNavigationDelegate>
@property (nonatomic,readonly) GCDAccessor *testDataAccessor;
@property (nonatomic) NSMutableDictionary <NSString *,NSString *>* testDic;

@end
- (void)initData{
    _testDataAccessor = [[GCDAccessor alloc]init];
    self.testDic = [NSMutableDictionary<NSString*,NSString*> dictionary];
}

-(void)settestDicWithString:(NSString *)str andKey:(NSString*)key{
    [_testDataAccessor writeWithGCD:^{
        self.testDic = [NSMutableDictionary dictionaryWithObject:str forKey:key];
    }];
}
-(NSString *)gettestDicWithString:(NSString *)str{
    return [_testDataAccessor readWithGCD:^id _Nonnull{
        return self.testDic[str];
    }];
}

In contrast, if the abuse @synchronized (self) very inappropriate, because all synchronization blocks (synchroization block) will grab a lock with each other. If there are so many attributes to write, then sync blocks of each property (synchroization block) have to wait for all other sync blocks (synchroization block) is finished to perform, which is probably not what I wanted.

In the queue, the fence block must be performed separately, not in parallel with other blocks. This only makes sense for concurrent queue, because the serial was originally performed by one order. If you find concurrent queue block to be processed next block was a fence (barrier block), so long has been to wait until the current block are all concurrent execution is completed, will execute this block alone fence, the fence to be executed after the block, then the normal way to continue country processing. That is to say, when we were set, and the block is performed separately, so you do not write data to a plurality of threads simultaneously.

Dispatch_barrier using this methodology can be applied in various types of objects inside the read operation.

 

 

Guess you like

Origin www.cnblogs.com/qzCodeDiary/p/11844255.html