├── LXDDispatchOperation.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── linxinda.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcuserdata │ └── linxinda.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── LXDDispatchOperation.xcscheme └── project.pbxproj ├── LXDDispatchOperation ├── ViewController.h ├── GCD │ ├── LXDGCD.h │ ├── LXDGroup.h │ ├── LXDSemaphore.h │ ├── LXDTimer.h │ ├── LXDGroup.m │ ├── LXDSemaphore.m │ ├── LXDTimer.m │ ├── LXDQueue.h │ └── LXDQueue.m ├── AppDelegate.h ├── main.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Dispatch │ ├── LXDDispatchOperation.h │ ├── LXDDispatchAsync.h │ ├── LXDDispatchOperation.m │ └── LXDDispatchAsync.m ├── Info.plist ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard ├── ViewController.m └── AppDelegate.m ├── LXDDispatchOperationTests ├── Info.plist └── LXDDispatchOperationTests.m └── LXDDispatchOperationUITests ├── Info.plist └── LXDDispatchOperationUITests.m /LXDDispatchOperation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LXDDispatchOperation.xcodeproj/project.xcworkspace/xcuserdata/linxinda.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindrilin/LXDDispatchOperation/HEAD/LXDDispatchOperation.xcodeproj/project.xcworkspace/xcuserdata/linxinda.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LXDDispatchOperation/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDGCD.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDGCD.h 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/4. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #ifndef LXDGCD_h 10 | #define LXDGCD_h 11 | 12 | #import "LXDTimer.h" 13 | #import "LXDGroup.h" 14 | #import "LXDQueue.h" 15 | #import "LXDSemaphore.h" 16 | 17 | #endif /* LXDGCD_h */ 18 | -------------------------------------------------------------------------------- /LXDDispatchOperation/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /LXDDispatchOperation/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDGroup.h 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/3. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /*! 12 | * @brief 封装GCD任务组 13 | */ 14 | @interface LXDGroup : NSObject 15 | 16 | @property (nonatomic, readonly, strong) dispatch_group_t executeGroup; 17 | 18 | #pragma mark - 操作 19 | - (void)wait; 20 | - (void)enter; 21 | - (void)leave; 22 | - (BOOL)wait: (NSTimeInterval)delay; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDSemaphore.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDSemaphore.h 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/3. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /*! 12 | * @brief 封装GCD信号量 13 | */ 14 | @interface LXDSemaphore : NSObject 15 | 16 | @property (nonatomic, readonly, strong) dispatch_semaphore_t executeSemaphore; 17 | 18 | #pragma mark - 构造器 19 | - (instancetype)initWithValue: (NSUInteger)value; 20 | 21 | #pragma mark - 操作 22 | - (void)wait; 23 | - (BOOL)waitWithTimeout: (NSTimeInterval)timeout; 24 | - (BOOL)signal; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDTimer.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDTimer.h 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/4. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LXDQueue; 12 | /*! 13 | * @brief 封装GCD定时器 14 | */ 15 | @interface LXDTimer : NSObject 16 | 17 | @property (nonatomic, readonly, strong) dispatch_source_t executeSource; 18 | 19 | #pragma mark - 构造器 20 | - (instancetype)initWithExecuteQueue: (LXDQueue *)queue; 21 | 22 | #pragma mark - 操作 23 | - (void)execute: (dispatch_block_t)block interval: (NSTimeInterval)interval; 24 | - (void)execute: (dispatch_block_t)block interval: (NSTimeInterval)interval delay: (NSTimeInterval)delay; 25 | - (void)start; 26 | - (void)destory; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /LXDDispatchOperationTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LXDDispatchOperationUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /LXDDispatchOperation.xcodeproj/xcuserdata/linxinda.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LXDDispatchOperation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | EF5710D51E95CBE8007C5BA6 16 | 17 | primary 18 | 19 | 20 | EF5710EE1E95CBE8007C5BA6 21 | 22 | primary 23 | 24 | 25 | EF5710F91E95CBE8007C5BA6 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDGroup.m 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/3. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import "LXDGroup.h" 10 | 11 | @interface LXDGroup () 12 | 13 | @property (nonatomic, strong) dispatch_group_t executeGroup; 14 | 15 | @end 16 | 17 | 18 | @implementation LXDGroup 19 | 20 | - (instancetype)init 21 | { 22 | if (self = [super init]) { 23 | self.executeGroup = dispatch_group_create(); 24 | } 25 | return self; 26 | } 27 | 28 | - (void)wait 29 | { 30 | dispatch_group_wait(self.executeGroup, DISPATCH_TIME_FOREVER); 31 | } 32 | 33 | - (void)enter 34 | { 35 | dispatch_group_enter(self.executeGroup); 36 | } 37 | 38 | - (void)leave 39 | { 40 | dispatch_group_leave(self.executeGroup); 41 | } 42 | 43 | - (BOOL)wait: (NSTimeInterval)delay 44 | { 45 | return dispatch_group_wait(self.executeGroup, delay * NSEC_PER_SEC) == 0; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Dispatch/LXDDispatchOperation.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDDispatchOperation.h 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LXDDispatchOperation; 12 | typedef void(^LXDCancelableBlock)(LXDDispatchOperation * operation); 13 | 14 | 15 | /*! 16 | * @brief 派发任务封装 17 | */ 18 | @interface LXDDispatchOperation : NSObject 19 | 20 | @property (nonatomic, readonly) BOOL isCanceled; 21 | @property (nonatomic, readonly) dispatch_queue_t queue; 22 | 23 | + (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block; 24 | + (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block inQoS: (NSQualityOfService)qos; 25 | 26 | + (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block; 27 | + (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block inQos: (NSQualityOfService)qos; 28 | 29 | - (void)start; 30 | - (void)cancel; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /LXDDispatchOperationTests/LXDDispatchOperationTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDDispatchOperationTests.m 3 | // LXDDispatchOperationTests 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LXDDispatchOperationTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation LXDDispatchOperationTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDSemaphore.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDSemaphore.m 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/3. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import "LXDSemaphore.h" 10 | 11 | @interface LXDSemaphore () 12 | 13 | @property (nonatomic, strong) dispatch_semaphore_t executeSemaphore; 14 | 15 | @end 16 | 17 | 18 | @implementation LXDSemaphore 19 | 20 | - (instancetype)init 21 | { 22 | return [self initWithValue: 1]; 23 | } 24 | 25 | - (instancetype)initWithValue: (NSUInteger)value 26 | { 27 | if (self = [super init]) { 28 | self.executeSemaphore = dispatch_semaphore_create(value); 29 | } 30 | return self; 31 | } 32 | 33 | 34 | #pragma mark - 操作 35 | - (void)wait 36 | { 37 | dispatch_semaphore_wait(self.executeSemaphore, DISPATCH_TIME_FOREVER); 38 | } 39 | 40 | - (BOOL)waitWithTimeout: (NSTimeInterval)timeout 41 | { 42 | return dispatch_semaphore_wait(self.executeSemaphore, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC)) == 0; 43 | } 44 | 45 | - (BOOL)signal 46 | { 47 | return dispatch_semaphore_signal(self.executeSemaphore) != 0; 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Dispatch/LXDDispatchAsync.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDDispatchQueuePool.h 3 | // LXDAppMonitor 4 | // 5 | // Created by linxinda on 2017/4/2. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | typedef NS_ENUM(NSInteger, LXDQualityOfService) { 13 | LXDQualityOfServiceUserInteractive = NSQualityOfServiceUserInteractive, 14 | LXDQualityOfServiceUserInitiated = NSQualityOfServiceUserInitiated, 15 | LXDQualityOfServiceUtility = NSQualityOfServiceUtility, 16 | LXDQualityOfServiceBackground = NSQualityOfServiceBackground, 17 | LXDQualityOfServiceDefault = NSQualityOfServiceDefault, 18 | }; 19 | 20 | 21 | dispatch_queue_t LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfService qos, dispatch_block_t block); 22 | dispatch_queue_t LXDDispatchQueueAsyncBlockInUserInteractive(dispatch_block_t block); 23 | dispatch_queue_t LXDDispatchQueueAsyncBlockInUserInitiated(dispatch_block_t block); 24 | dispatch_queue_t LXDDispatchQueueAsyncBlockInBackground(dispatch_block_t block); 25 | dispatch_queue_t LXDDispatchQueueAsyncBlockInDefault(dispatch_block_t block); 26 | dispatch_queue_t LXDDispatchQueueAsyncBlockInUtility(dispatch_block_t block); 27 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /LXDDispatchOperationUITests/LXDDispatchOperationUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDDispatchOperationUITests.m 3 | // LXDDispatchOperationUITests 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LXDDispatchOperationUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation LXDDispatchOperationUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LXDDispatchOperation/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LXDGCD.h" 11 | #import "LXDDispatchAsync.h" 12 | #import "LXDDispatchOperation.h" 13 | 14 | 15 | @interface ViewController () 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | /// LXDGCD 26 | [LXDQueue executeInMainQueue: ^{ 27 | NSLog(@"This is main queue"); 28 | }]; 29 | [LXDQueue executeInGlobalQueue: ^{ 30 | NSLog(@"The code will be executed in global queue after 1 second"); 31 | } delay: 1]; 32 | 33 | /// LXDDispatch 34 | for (int idx = 0; idx < 10000; idx++) { 35 | NSQualityOfService qos = NSQualityOfServiceDefault; 36 | switch (arc4random() % 5) { 37 | case 0: 38 | qos = NSQualityOfServiceUserInteractive; 39 | break; 40 | case 1: 41 | qos = NSQualityOfServiceUserInitiated; 42 | break; 43 | case 2: 44 | qos = NSQualityOfServiceDefault; 45 | break; 46 | case 3: 47 | qos = NSQualityOfServiceUtility; 48 | break; 49 | case 4: 50 | qos = NSQualityOfServiceBackground; 51 | break; 52 | } 53 | [[LXDDispatchOperation dispatchOperationWithBlock: ^{ 54 | NSLog(@"async block in %@", [self descriptionForQos: qos]); 55 | } inQoS: qos] start]; 56 | } 57 | } 58 | 59 | - (NSString *)descriptionForQos: (NSQualityOfService)qos { 60 | switch (qos) { 61 | case NSQualityOfServiceUserInteractive: 62 | return @"user interactive"; 63 | case NSQualityOfServiceUserInitiated: 64 | return @"User Initiated"; 65 | case NSQualityOfServiceDefault: 66 | return @"Default"; 67 | case NSQualityOfServiceUtility: 68 | return @"Utility"; 69 | case NSQualityOfServiceBackground: 70 | return @"Background"; 71 | } 72 | } 73 | 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /LXDDispatchOperation/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDTimer.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDTimer.m 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/5/4. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import "LXDTimer.h" 10 | #import "LXDQueue.h" 11 | 12 | @interface LXDTimer () 13 | 14 | @property (nonatomic, copy) dispatch_block_t block; 15 | @property (nonatomic, assign) NSTimeInterval interval; 16 | @property (nonatomic, strong) dispatch_queue_t executeQueue; 17 | @property (nonatomic, strong) dispatch_source_t executeSource; 18 | 19 | @end 20 | 21 | 22 | @implementation LXDTimer 23 | 24 | 25 | #pragma mark - 构造器 26 | - (instancetype)init 27 | { 28 | if (self = [super init]) { 29 | self.executeQueue = [LXDQueue defaultPriorityQueue].executeQueue; 30 | self.executeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, LXDQueue.defaultPriorityQueue.executeQueue); 31 | } 32 | return self; 33 | } 34 | 35 | - (instancetype)initWithExecuteQueue: (LXDQueue *)queue 36 | { 37 | if (self = [super init]) { 38 | self.executeQueue = queue.executeQueue; 39 | self.executeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue.executeQueue); 40 | } 41 | return self; 42 | } 43 | 44 | - (void)dealloc 45 | { 46 | [self destory]; 47 | } 48 | 49 | 50 | #pragma mark - 操作 51 | - (void)execute: (dispatch_block_t)block interval: (NSTimeInterval)interval 52 | { 53 | [self execute: block interval: interval delay: 0]; 54 | } 55 | 56 | - (void)execute: (dispatch_block_t)block interval: (NSTimeInterval)interval delay: (NSTimeInterval)delay 57 | { 58 | NSParameterAssert(block); 59 | self.block = block; 60 | self.interval = interval; 61 | dispatch_source_set_timer(self.executeSource, dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0); 62 | dispatch_source_set_event_handler(self.executeSource, block); 63 | } 64 | 65 | - (void)start 66 | { 67 | if (!_executeSource) { 68 | self.executeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _executeQueue); 69 | [self execute: _block interval: _interval]; 70 | } 71 | dispatch_resume(self.executeSource); 72 | } 73 | 74 | - (void)destory 75 | { 76 | if (_executeSource) { 77 | dispatch_source_cancel(self.executeSource); 78 | self.executeSource = nil; 79 | } 80 | } 81 | 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // LXDQueue.h 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/4/29. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LXDGroup; 12 | @class LXDSemaphore; 13 | 14 | /*! 15 | * @brief 线程优先等级 16 | */ 17 | typedef NS_ENUM(NSInteger, LXDQueuePriority) { 18 | /// 最低优先级 19 | LXDLowPriority = DISPATCH_QUEUE_PRIORITY_LOW, 20 | /// 最高优先级 21 | LXDHighPriority = DISPATCH_QUEUE_PRIORITY_HIGH, 22 | /// 默认优先级 23 | LXDDefaultPriority = DISPATCH_QUEUE_PRIORITY_DEFAULT, 24 | /// 后台优先级 25 | LXDBackgroundPriority = DISPATCH_QUEUE_PRIORITY_BACKGROUND 26 | }; 27 | 28 | /*! 29 | * @brief 封装GCD队列 30 | */ 31 | @interface LXDQueue : NSObject 32 | 33 | @property (nonatomic, readonly, strong) dispatch_queue_t executeQueue; 34 | 35 | #pragma mark - 获取线程 36 | + (instancetype)mainQueue; 37 | + (instancetype)lowPriorityQueue; 38 | + (instancetype)highPriorityQueue; 39 | + (instancetype)defaultPriorityQueue; 40 | + (instancetype)backgroundPriorityQueue; 41 | 42 | #pragma mark - 便利方法 43 | + (void)executeInMainQueue: (dispatch_block_t)block; 44 | + (void)executeInGlobalQueue: (dispatch_block_t)block; 45 | + (void)executeInGlobalQueue: (dispatch_block_t)block queuePriority: (LXDQueuePriority)queuePriority; 46 | 47 | + (void)executeInMainQueue: (dispatch_block_t)block delay: (NSTimeInterval)delay; 48 | + (void)executeInGlobalQueue: (dispatch_block_t)block delay: (NSTimeInterval)delay; 49 | + (void)executeInGlobalQueue: (dispatch_block_t)block queuePriority: (LXDQueuePriority)queuePriority delay: (NSTimeInterval)delay; 50 | 51 | #pragma mark - 创建线程 52 | - (instancetype)init; 53 | - (instancetype)initSerial; 54 | - (instancetype)initSerialWithIdentifier: (NSString *)identifier; 55 | - (instancetype)initConcurrent; 56 | - (instancetype)initConcurrentWithIdentifier: (NSString *)identifier; 57 | 58 | #pragma mark - 操作 59 | - (void)execute: (dispatch_block_t)block; 60 | - (void)execute: (dispatch_block_t)block delay: (NSTimeInterval)delay; 61 | - (void)execute: (dispatch_block_t)block wait: (LXDSemaphore *)semaphore; 62 | - (void)execute: (dispatch_block_t)block delay: (NSTimeInterval)delay wait: (LXDSemaphore *)semaphore; 63 | 64 | - (void)resume; 65 | - (void)suspend; 66 | - (void)barrierExecute: (dispatch_block_t)block; 67 | 68 | #pragma mark - 其他操作 69 | - (void)notify: (dispatch_block_t)block inGroup: (LXDGroup *)group; 70 | - (void)execute: (dispatch_block_t)block inGroup: (LXDGroup *)group; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Dispatch/LXDDispatchOperation.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDDispatchOperation.m 3 | // LXDDispatchOperation 4 | // 5 | // Created by linxinda on 2017/4/6. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import "LXDDispatchOperation.h" 10 | #import "LXDDispatchAsync.h" 11 | 12 | 13 | #ifndef LXDDispatchAsync_m 14 | #define LXD_INLINE static inline 15 | #endif 16 | 17 | #define LXD_FUNCTION_OVERLOAD __attribute__((overloadable)) 18 | 19 | 20 | LXD_INLINE LXD_FUNCTION_OVERLOAD void __LXDLockExecute(dispatch_block_t block, dispatch_time_t threshold); 21 | 22 | LXD_INLINE LXD_FUNCTION_OVERLOAD void __LXDLockExecute(dispatch_block_t block) { 23 | __LXDLockExecute(block, dispatch_time(DISPATCH_TIME_NOW, DISPATCH_TIME_FOREVER)); 24 | } 25 | 26 | LXD_INLINE LXD_FUNCTION_OVERLOAD void __LXDLockExecute(dispatch_block_t block, dispatch_time_t threshold) { 27 | if (block == nil) { return ; } 28 | static dispatch_semaphore_t lxd_queue_semaphore; 29 | static dispatch_once_t once; 30 | dispatch_once(&once, ^{ 31 | lxd_queue_semaphore = dispatch_semaphore_create(0); 32 | }); 33 | dispatch_semaphore_wait(lxd_queue_semaphore, threshold); 34 | block(); 35 | dispatch_semaphore_signal(lxd_queue_semaphore); 36 | } 37 | 38 | 39 | @interface LXDDispatchOperation () 40 | 41 | @property (nonatomic, assign) BOOL isCanceled; 42 | @property (nonatomic, assign) BOOL isExcuting; 43 | @property (nonatomic, assign) dispatch_queue_t queue; 44 | @property (nonatomic, assign) dispatch_queue_t (*asyn)(dispatch_block_t); 45 | @property (nonatomic, copy) LXDCancelableBlock cancelableBlock; 46 | 47 | @end 48 | 49 | 50 | @implementation LXDDispatchOperation 51 | 52 | 53 | + (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block { 54 | return [self dispatchOperationWithCancelableBlock: ^(LXDDispatchOperation *operation) { 55 | if (!operation.isCanceled) { 56 | block(); 57 | } 58 | } inQos: NSQualityOfServiceDefault]; 59 | } 60 | 61 | + (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block inQoS: (NSQualityOfService)qos { 62 | return [self dispatchOperationWithCancelableBlock: ^(LXDDispatchOperation *operation) { 63 | if (!operation.isCanceled) { 64 | block(); 65 | } 66 | } inQos: qos]; 67 | } 68 | 69 | + (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block { 70 | return [self dispatchOperationWithCancelableBlock: block inQos: NSQualityOfServiceDefault]; 71 | } 72 | 73 | + (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block inQos: (NSQualityOfService)qos { 74 | return [[self alloc] initWithBlock: block inQos: qos]; 75 | } 76 | 77 | - (instancetype)initWithBlock: (LXDCancelableBlock)block inQos: (NSQualityOfService)qos { 78 | if (block == nil) { return nil; } 79 | if (self = [super init]) { 80 | switch (qos) { 81 | case NSQualityOfServiceUserInteractive: 82 | self.asyn = LXDDispatchQueueAsyncBlockInUserInteractive; 83 | break; 84 | case NSQualityOfServiceUserInitiated: 85 | self.asyn = LXDDispatchQueueAsyncBlockInUserInitiated; 86 | break; 87 | case NSQualityOfServiceDefault: 88 | self.asyn = LXDDispatchQueueAsyncBlockInDefault; 89 | break; 90 | case NSQualityOfServiceUtility: 91 | self.asyn = LXDDispatchQueueAsyncBlockInUtility; 92 | break; 93 | case NSQualityOfServiceBackground: 94 | self.asyn = LXDDispatchQueueAsyncBlockInBackground; 95 | break; 96 | default: 97 | self.asyn = LXDDispatchQueueAsyncBlockInDefault; 98 | break; 99 | } 100 | self.cancelableBlock = block; 101 | } 102 | return self; 103 | } 104 | 105 | - (void)dealloc { 106 | [self cancel]; 107 | } 108 | 109 | - (void)start { 110 | __LXDLockExecute(^{ 111 | self.queue = self.asyn(^{ 112 | self.cancelableBlock(self); 113 | self.cancelableBlock = nil; 114 | }); 115 | self.isExcuting = YES; 116 | }); 117 | } 118 | 119 | - (void)cancel { 120 | __LXDLockExecute(^{ 121 | self.isCanceled = YES; 122 | if (!self.isExcuting) { 123 | self.asyn = NULL; 124 | self.cancelableBlock = nil; 125 | } 126 | }); 127 | } 128 | 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /LXDDispatchOperation.xcodeproj/xcuserdata/linxinda.xcuserdatad/xcschemes/LXDDispatchOperation.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /LXDDispatchOperation/GCD/LXDQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDQueue.m 3 | // LXDPersonalBlog 4 | // 5 | // Created by 林欣达 on 16/4/29. 6 | // Copyright © 2016年 SindriLin. All rights reserved. 7 | // 8 | 9 | #import "LXDQueue.h" 10 | #import "LXDGroup.h" 11 | #import "LXDSemaphore.h" 12 | 13 | static LXDQueue * mainQueue; 14 | static LXDQueue * lowPriorityQueue; 15 | static LXDQueue * highPriorityQueue; 16 | static LXDQueue * defaultPriorityQueue; 17 | static LXDQueue * backgroundPriorityQueue; 18 | 19 | @interface LXDQueue () 20 | 21 | @property (nonatomic, strong) dispatch_queue_t executeQueue; 22 | 23 | @end 24 | 25 | 26 | @implementation LXDQueue 27 | 28 | 29 | #pragma mark - 获取线程 30 | + (instancetype)mainQueue 31 | { 32 | return mainQueue; 33 | } 34 | 35 | + (instancetype)lowPriorityQueue 36 | { 37 | return lowPriorityQueue; 38 | } 39 | 40 | + (instancetype)highPriorityQueue 41 | { 42 | return highPriorityQueue; 43 | } 44 | 45 | + (instancetype)defaultPriorityQueue 46 | { 47 | return defaultPriorityQueue; 48 | } 49 | 50 | + (instancetype)backgroundPriorityQueue 51 | { 52 | return backgroundPriorityQueue; 53 | } 54 | 55 | + (void)initialize 56 | { 57 | if (self == [LXDQueue self]) { 58 | mainQueue = [LXDQueue new]; 59 | lowPriorityQueue = [LXDQueue new]; 60 | highPriorityQueue = [LXDQueue new]; 61 | defaultPriorityQueue = [LXDQueue new]; 62 | backgroundPriorityQueue = [LXDQueue new]; 63 | 64 | mainQueue.executeQueue = dispatch_get_main_queue(); 65 | lowPriorityQueue.executeQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); 66 | highPriorityQueue.executeQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 67 | defaultPriorityQueue.executeQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 68 | backgroundPriorityQueue.executeQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); 69 | } 70 | } 71 | 72 | 73 | #pragma mark - 便利方法 74 | + (void)executeInMainQueue: (dispatch_block_t)block 75 | { 76 | NSParameterAssert(block); 77 | dispatch_async(dispatch_get_main_queue(), block); 78 | } 79 | 80 | + (void)executeInGlobalQueue: (dispatch_block_t)block 81 | { 82 | NSParameterAssert(block); 83 | dispatch_async(dispatch_get_global_queue(LXDDefaultPriority, 0), block); 84 | } 85 | 86 | + (void)executeInGlobalQueue: (dispatch_block_t)block queuePriority: (LXDQueuePriority)queuePriority 87 | { 88 | NSParameterAssert(block); 89 | dispatch_async(dispatch_get_global_queue(queuePriority, 0), block); 90 | } 91 | 92 | + (void)executeInMainQueue: (dispatch_block_t)block delay: (NSTimeInterval)delay 93 | { 94 | NSParameterAssert(block); 95 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_main_queue(), block); 96 | } 97 | 98 | + (void)executeInGlobalQueue: (dispatch_block_t)block delay: (NSTimeInterval)delay 99 | { 100 | NSParameterAssert(block); 101 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_global_queue(LXDDefaultPriority, 0), block); 102 | } 103 | 104 | + (void)executeInGlobalQueue: (dispatch_block_t)block queuePriority: (LXDQueuePriority)queuePriority delay: (NSTimeInterval)delay 105 | { 106 | NSParameterAssert(block); 107 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_global_queue(queuePriority, 0), block); 108 | } 109 | 110 | 111 | #pragma mark - 创建线程 112 | - (instancetype)init 113 | { 114 | return [self initSerial]; 115 | } 116 | 117 | - (instancetype)initSerial 118 | { 119 | if (self = [super init]) { 120 | self.executeQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); 121 | } 122 | return self; 123 | } 124 | 125 | - (instancetype)initSerialWithIdentifier: (NSString *)identifier 126 | { 127 | if (self = [super init]) { 128 | self.executeQueue = dispatch_queue_create(identifier.UTF8String, DISPATCH_QUEUE_SERIAL); 129 | } 130 | return self; 131 | } 132 | 133 | - (instancetype)initConcurrent 134 | { 135 | if (self = [super init]) { 136 | self.executeQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT); 137 | } 138 | return self; 139 | } 140 | 141 | - (instancetype)initConcurrentWithIdentifier: (NSString *)identifier 142 | { 143 | if (self = [super init]) { 144 | self.executeQueue = dispatch_queue_create(identifier.UTF8String, DISPATCH_QUEUE_CONCURRENT); 145 | } 146 | return self; 147 | } 148 | 149 | 150 | #pragma mark - 任务 151 | - (void)execute: (dispatch_block_t)block 152 | { 153 | NSParameterAssert(block); 154 | dispatch_async(self.executeQueue, block); 155 | } 156 | 157 | - (void)execute: (dispatch_block_t)block delay: (NSTimeInterval)delay 158 | { 159 | NSParameterAssert(block); 160 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), self.executeQueue, block); 161 | } 162 | 163 | - (void)execute: (dispatch_block_t)block wait: (LXDSemaphore *)semaphore 164 | { 165 | NSParameterAssert(block); 166 | dispatch_block_t executeBlock = ^{ 167 | [semaphore wait]; 168 | block(); 169 | [semaphore signal]; 170 | }; 171 | dispatch_async(self.executeQueue, executeBlock); 172 | } 173 | 174 | - (void)execute: (dispatch_block_t)block delay: (NSTimeInterval)delay wait: (LXDSemaphore *)semaphore 175 | { 176 | NSParameterAssert(block); 177 | dispatch_block_t executeBlock = ^{ 178 | [semaphore wait]; 179 | block(); 180 | [semaphore signal]; 181 | }; 182 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), self.executeQueue, executeBlock); 183 | } 184 | 185 | - (void)resume 186 | { 187 | dispatch_resume(self.executeQueue); 188 | } 189 | 190 | - (void)suspend 191 | { 192 | dispatch_suspend(self.executeQueue); 193 | } 194 | 195 | - (void)barrierExecute: (dispatch_block_t)block 196 | { 197 | NSParameterAssert(block); 198 | dispatch_barrier_async(self.executeQueue, block); 199 | } 200 | 201 | 202 | #pragma mark - 其他操作 203 | - (void)execute: (dispatch_block_t)block inGroup: (LXDGroup *)group 204 | { 205 | NSParameterAssert(block); 206 | dispatch_group_async(group.executeGroup, self.executeQueue, block); 207 | } 208 | 209 | - (void)notify: (dispatch_block_t)block inGroup: (LXDGroup *)group 210 | { 211 | NSParameterAssert(block); 212 | dispatch_group_notify(group.executeGroup, self.executeQueue, block); 213 | } 214 | 215 | 216 | @end 217 | -------------------------------------------------------------------------------- /LXDDispatchOperation/Dispatch/LXDDispatchAsync.m: -------------------------------------------------------------------------------- 1 | // 2 | // LXDDispatchQueuePool.m 3 | // LXDAppMonitor 4 | // 5 | // Created by linxinda on 2017/4/2. 6 | // Copyright © 2017年 Jolimark. All rights reserved. 7 | // 8 | 9 | #import "LXDDispatchAsync.h" 10 | #import 11 | 12 | 13 | #ifndef LXDDispatchAsync_m 14 | #define LXDDispatchAsync_m 15 | #endif 16 | 17 | #define LXD_INLINE static inline 18 | #define LXD_QUEUE_MAX_COUNT 32 19 | 20 | 21 | typedef struct __LXDDispatchContext { 22 | const char * name; 23 | void ** queues; 24 | uint32_t queueCount; 25 | int32_t offset; 26 | } *DispatchContext, LXDDispatchContext; 27 | 28 | 29 | LXD_INLINE dispatch_queue_priority_t __LXDQualityOfServiceToDispatchPriority(LXDQualityOfService qos) { 30 | switch (qos) { 31 | case LXDQualityOfServiceUserInteractive: return DISPATCH_QUEUE_PRIORITY_HIGH; 32 | case LXDQualityOfServiceUserInitiated: return DISPATCH_QUEUE_PRIORITY_HIGH; 33 | case LXDQualityOfServiceUtility: return DISPATCH_QUEUE_PRIORITY_LOW; 34 | case LXDQualityOfServiceBackground: return DISPATCH_QUEUE_PRIORITY_BACKGROUND; 35 | case LXDQualityOfServiceDefault: return DISPATCH_QUEUE_PRIORITY_DEFAULT; 36 | default: return DISPATCH_QUEUE_PRIORITY_DEFAULT; 37 | } 38 | } 39 | 40 | LXD_INLINE qos_class_t __LXDQualityOfServiceToQOSClass(LXDQualityOfService qos) { 41 | switch (qos) { 42 | case LXDQualityOfServiceUserInteractive: return QOS_CLASS_USER_INTERACTIVE; 43 | case LXDQualityOfServiceUserInitiated: return QOS_CLASS_USER_INITIATED; 44 | case LXDQualityOfServiceUtility: return QOS_CLASS_UTILITY; 45 | case LXDQualityOfServiceBackground: return QOS_CLASS_BACKGROUND; 46 | case LXDQualityOfServiceDefault: return QOS_CLASS_DEFAULT; 47 | default: return QOS_CLASS_UNSPECIFIED; 48 | } 49 | } 50 | 51 | LXD_INLINE dispatch_queue_t __LXDQualityOfServiceToDispatchQueue(LXDQualityOfService qos, const char * queueName) { 52 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { 53 | dispatch_qos_class_t qosClass = __LXDQualityOfServiceToQOSClass(qos); 54 | dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, qosClass, 0); 55 | return dispatch_queue_create(queueName, attr); 56 | } else { 57 | dispatch_queue_t queue = dispatch_queue_create(queueName, DISPATCH_QUEUE_SERIAL); 58 | dispatch_set_target_queue(queue, dispatch_get_global_queue(__LXDQualityOfServiceToDispatchPriority(qos), 0)); 59 | return queue; 60 | } 61 | } 62 | 63 | LXD_INLINE DispatchContext __LXDDispatchContextCreate(const char * name, 64 | uint32_t queueCount, 65 | LXDQualityOfService qos) { 66 | DispatchContext context = calloc(1, sizeof(LXDDispatchContext)); 67 | if (context == NULL) { return NULL; } 68 | 69 | context->queues = calloc(queueCount, sizeof(void *)); 70 | if (context->queues == NULL) { 71 | free(context); 72 | return NULL; 73 | } 74 | for (int idx = 0; idx < queueCount; idx++) { 75 | context->queues[idx] = (__bridge_retained void *)__LXDQualityOfServiceToDispatchQueue(qos, name); 76 | } 77 | context->queueCount = queueCount; 78 | if (name) { 79 | context->name = strdup(name); 80 | } 81 | context->offset = 0; 82 | return context; 83 | } 84 | 85 | LXD_INLINE void __LXDDispatchContextRelease(DispatchContext context) { 86 | if (context == NULL) { return; } 87 | if (context->queues != NULL) { free(context->queues); } 88 | if (context->name != NULL) { free((void *)context->name); } 89 | context->queues = NULL; 90 | if (context) { free(context); } 91 | } 92 | 93 | LXD_INLINE dispatch_semaphore_t __LXDSemaphore() { 94 | static dispatch_semaphore_t semaphore; 95 | static dispatch_once_t once; 96 | dispatch_once(&once, ^{ 97 | semaphore = dispatch_semaphore_create(0); 98 | }); 99 | return semaphore; 100 | } 101 | 102 | LXD_INLINE dispatch_queue_t __LXDDispatchContextGetQueue(DispatchContext context) { 103 | dispatch_semaphore_wait(__LXDSemaphore(), dispatch_time(DISPATCH_TIME_NOW, DISPATCH_TIME_FOREVER)); 104 | uint32_t offset = (uint32_t)OSAtomicIncrement32(&context->offset); 105 | dispatch_queue_t queue = (__bridge dispatch_queue_t)context->queues[offset % context->queueCount]; 106 | dispatch_semaphore_signal(__LXDSemaphore()); 107 | if (queue) { return queue; } 108 | return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 109 | } 110 | 111 | LXD_INLINE DispatchContext __LXDDispatchContextGetForQos(LXDQualityOfService qos) { 112 | static DispatchContext contexts[5]; 113 | int count = (int)[NSProcessInfo processInfo].activeProcessorCount; 114 | count = MIN(1, MAX(count, LXD_QUEUE_MAX_COUNT)); 115 | switch (qos) { 116 | case LXDQualityOfServiceUserInteractive: { 117 | static dispatch_once_t once; 118 | dispatch_once(&once, ^{ 119 | contexts[0] = __LXDDispatchContextCreate("com.sindrilin.user_interactive", count, qos); 120 | }); 121 | return contexts[0]; 122 | } 123 | 124 | case LXDQualityOfServiceUserInitiated: { 125 | static dispatch_once_t once; 126 | dispatch_once(&once, ^{ 127 | contexts[1] = __LXDDispatchContextCreate("com.sindrilin.user_initated", count, qos); 128 | }); 129 | return contexts[1]; 130 | } 131 | 132 | case LXDQualityOfServiceUtility: { 133 | static dispatch_once_t once; 134 | dispatch_once(&once, ^{ 135 | contexts[2] = __LXDDispatchContextCreate("com.sindrilin.utility", count, qos); 136 | }); 137 | return contexts[2]; 138 | } 139 | 140 | case LXDQualityOfServiceBackground: { 141 | static dispatch_once_t once; 142 | dispatch_once(&once, ^{ 143 | contexts[3] = __LXDDispatchContextCreate("com.sindrilin.background", count, qos); 144 | }); 145 | return contexts[3]; 146 | } 147 | 148 | case LXDQualityOfServiceDefault: 149 | default: { 150 | static dispatch_once_t once; 151 | dispatch_once(&once, ^{ 152 | contexts[4] = __LXDDispatchContextCreate("com.sindrilin.default", count, qos); 153 | }); 154 | return contexts[4]; 155 | } 156 | } 157 | } 158 | 159 | dispatch_queue_t LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfService qos, dispatch_block_t block) { 160 | if (block == nil) { return NULL; } 161 | DispatchContext context = __LXDDispatchContextGetForQos(qos); 162 | dispatch_queue_t queue = __LXDDispatchContextGetQueue(context); 163 | dispatch_async(queue, block); 164 | return queue; 165 | } 166 | 167 | dispatch_queue_t LXDDispatchQueueAsyncBlockInUserInteractive(dispatch_block_t block) { 168 | return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceUserInteractive, block); 169 | } 170 | 171 | dispatch_queue_t LXDDispatchQueueAsyncBlockInUserInitiated(dispatch_block_t block) { 172 | return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceUserInitiated, block); 173 | } 174 | 175 | dispatch_queue_t LXDDispatchQueueAsyncBlockInUtility(dispatch_block_t block) { 176 | return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceUtility, block); 177 | } 178 | 179 | dispatch_queue_t LXDDispatchQueueAsyncBlockInBackground(dispatch_block_t block) { 180 | return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceBackground, block); 181 | } 182 | 183 | dispatch_queue_t LXDDispatchQueueAsyncBlockInDefault(dispatch_block_t block) { 184 | return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceDefault, block); 185 | } 186 | 187 | -------------------------------------------------------------------------------- /LXDDispatchOperation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | EF5710DB1E95CBE8007C5BA6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5710DA1E95CBE8007C5BA6 /* main.m */; }; 11 | EF5710DE1E95CBE8007C5BA6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5710DD1E95CBE8007C5BA6 /* AppDelegate.m */; }; 12 | EF5710E11E95CBE8007C5BA6 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5710E01E95CBE8007C5BA6 /* ViewController.m */; }; 13 | EF5710E41E95CBE8007C5BA6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EF5710E21E95CBE8007C5BA6 /* Main.storyboard */; }; 14 | EF5710E61E95CBE8007C5BA6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EF5710E51E95CBE8007C5BA6 /* Assets.xcassets */; }; 15 | EF5710E91E95CBE8007C5BA6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EF5710E71E95CBE8007C5BA6 /* LaunchScreen.storyboard */; }; 16 | EF5710F41E95CBE8007C5BA6 /* LXDDispatchOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5710F31E95CBE8007C5BA6 /* LXDDispatchOperationTests.m */; }; 17 | EF5710FF1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5710FE1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.m */; }; 18 | EF57110F1E95CC07007C5BA6 /* LXDDispatchAsync.m in Sources */ = {isa = PBXBuildFile; fileRef = EF57110E1E95CC07007C5BA6 /* LXDDispatchAsync.m */; }; 19 | EF5711121E95CC63007C5BA6 /* LXDDispatchOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5711111E95CC63007C5BA6 /* LXDDispatchOperation.m */; }; 20 | EF57111D1E9615E4007C5BA6 /* LXDGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5711161E9615E4007C5BA6 /* LXDGroup.m */; }; 21 | EF57111E1E9615E4007C5BA6 /* LXDQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = EF5711181E9615E4007C5BA6 /* LXDQueue.m */; }; 22 | EF57111F1E9615E4007C5BA6 /* LXDSemaphore.m in Sources */ = {isa = PBXBuildFile; fileRef = EF57111A1E9615E4007C5BA6 /* LXDSemaphore.m */; }; 23 | EF5711201E9615E4007C5BA6 /* LXDTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = EF57111C1E9615E4007C5BA6 /* LXDTimer.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | EF5710F01E95CBE8007C5BA6 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = EF5710CE1E95CBE8007C5BA6 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = EF5710D51E95CBE8007C5BA6; 32 | remoteInfo = LXDDispatchOperation; 33 | }; 34 | EF5710FB1E95CBE8007C5BA6 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = EF5710CE1E95CBE8007C5BA6 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = EF5710D51E95CBE8007C5BA6; 39 | remoteInfo = LXDDispatchOperation; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | EF5710D61E95CBE8007C5BA6 /* LXDDispatchOperation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LXDDispatchOperation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | EF5710DA1E95CBE8007C5BA6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | EF5710DC1E95CBE8007C5BA6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 47 | EF5710DD1E95CBE8007C5BA6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 48 | EF5710DF1E95CBE8007C5BA6 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 49 | EF5710E01E95CBE8007C5BA6 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 50 | EF5710E31E95CBE8007C5BA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | EF5710E51E95CBE8007C5BA6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | EF5710E81E95CBE8007C5BA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | EF5710EA1E95CBE8007C5BA6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | EF5710EF1E95CBE8007C5BA6 /* LXDDispatchOperationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LXDDispatchOperationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | EF5710F31E95CBE8007C5BA6 /* LXDDispatchOperationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXDDispatchOperationTests.m; sourceTree = ""; }; 56 | EF5710F51E95CBE8007C5BA6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | EF5710FA1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LXDDispatchOperationUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | EF5710FE1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXDDispatchOperationUITests.m; sourceTree = ""; }; 59 | EF5711001E95CBE8007C5BA6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | EF57110D1E95CC07007C5BA6 /* LXDDispatchAsync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDDispatchAsync.h; sourceTree = ""; }; 61 | EF57110E1E95CC07007C5BA6 /* LXDDispatchAsync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDDispatchAsync.m; sourceTree = ""; }; 62 | EF5711101E95CC63007C5BA6 /* LXDDispatchOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDDispatchOperation.h; sourceTree = ""; }; 63 | EF5711111E95CC63007C5BA6 /* LXDDispatchOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDDispatchOperation.m; sourceTree = ""; }; 64 | EF5711141E9615E4007C5BA6 /* LXDGCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDGCD.h; sourceTree = ""; }; 65 | EF5711151E9615E4007C5BA6 /* LXDGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDGroup.h; sourceTree = ""; }; 66 | EF5711161E9615E4007C5BA6 /* LXDGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDGroup.m; sourceTree = ""; }; 67 | EF5711171E9615E4007C5BA6 /* LXDQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDQueue.h; sourceTree = ""; }; 68 | EF5711181E9615E4007C5BA6 /* LXDQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDQueue.m; sourceTree = ""; }; 69 | EF5711191E9615E4007C5BA6 /* LXDSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDSemaphore.h; sourceTree = ""; }; 70 | EF57111A1E9615E4007C5BA6 /* LXDSemaphore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDSemaphore.m; sourceTree = ""; }; 71 | EF57111B1E9615E4007C5BA6 /* LXDTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDTimer.h; sourceTree = ""; }; 72 | EF57111C1E9615E4007C5BA6 /* LXDTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDTimer.m; sourceTree = ""; }; 73 | /* End PBXFileReference section */ 74 | 75 | /* Begin PBXFrameworksBuildPhase section */ 76 | EF5710D31E95CBE8007C5BA6 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | EF5710EC1E95CBE8007C5BA6 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | EF5710F71E95CBE8007C5BA6 /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | /* End PBXFrameworksBuildPhase section */ 98 | 99 | /* Begin PBXGroup section */ 100 | EF5710CD1E95CBE8007C5BA6 = { 101 | isa = PBXGroup; 102 | children = ( 103 | EF5710D81E95CBE8007C5BA6 /* LXDDispatchOperation */, 104 | EF5710F21E95CBE8007C5BA6 /* LXDDispatchOperationTests */, 105 | EF5710FD1E95CBE8007C5BA6 /* LXDDispatchOperationUITests */, 106 | EF5710D71E95CBE8007C5BA6 /* Products */, 107 | ); 108 | sourceTree = ""; 109 | }; 110 | EF5710D71E95CBE8007C5BA6 /* Products */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | EF5710D61E95CBE8007C5BA6 /* LXDDispatchOperation.app */, 114 | EF5710EF1E95CBE8007C5BA6 /* LXDDispatchOperationTests.xctest */, 115 | EF5710FA1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.xctest */, 116 | ); 117 | name = Products; 118 | sourceTree = ""; 119 | }; 120 | EF5710D81E95CBE8007C5BA6 /* LXDDispatchOperation */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | EF5711131E9615E4007C5BA6 /* GCD */, 124 | EF57110C1E95CC07007C5BA6 /* Dispatch */, 125 | EF5710DC1E95CBE8007C5BA6 /* AppDelegate.h */, 126 | EF5710DD1E95CBE8007C5BA6 /* AppDelegate.m */, 127 | EF5710DF1E95CBE8007C5BA6 /* ViewController.h */, 128 | EF5710E01E95CBE8007C5BA6 /* ViewController.m */, 129 | EF5710E21E95CBE8007C5BA6 /* Main.storyboard */, 130 | EF5710E51E95CBE8007C5BA6 /* Assets.xcassets */, 131 | EF5710E71E95CBE8007C5BA6 /* LaunchScreen.storyboard */, 132 | EF5710EA1E95CBE8007C5BA6 /* Info.plist */, 133 | EF5710D91E95CBE8007C5BA6 /* Supporting Files */, 134 | ); 135 | path = LXDDispatchOperation; 136 | sourceTree = ""; 137 | }; 138 | EF5710D91E95CBE8007C5BA6 /* Supporting Files */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | EF5710DA1E95CBE8007C5BA6 /* main.m */, 142 | ); 143 | name = "Supporting Files"; 144 | sourceTree = ""; 145 | }; 146 | EF5710F21E95CBE8007C5BA6 /* LXDDispatchOperationTests */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | EF5710F31E95CBE8007C5BA6 /* LXDDispatchOperationTests.m */, 150 | EF5710F51E95CBE8007C5BA6 /* Info.plist */, 151 | ); 152 | path = LXDDispatchOperationTests; 153 | sourceTree = ""; 154 | }; 155 | EF5710FD1E95CBE8007C5BA6 /* LXDDispatchOperationUITests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | EF5710FE1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.m */, 159 | EF5711001E95CBE8007C5BA6 /* Info.plist */, 160 | ); 161 | path = LXDDispatchOperationUITests; 162 | sourceTree = ""; 163 | }; 164 | EF57110C1E95CC07007C5BA6 /* Dispatch */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | EF5711101E95CC63007C5BA6 /* LXDDispatchOperation.h */, 168 | EF5711111E95CC63007C5BA6 /* LXDDispatchOperation.m */, 169 | EF57110D1E95CC07007C5BA6 /* LXDDispatchAsync.h */, 170 | EF57110E1E95CC07007C5BA6 /* LXDDispatchAsync.m */, 171 | ); 172 | path = Dispatch; 173 | sourceTree = ""; 174 | }; 175 | EF5711131E9615E4007C5BA6 /* GCD */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | EF5711141E9615E4007C5BA6 /* LXDGCD.h */, 179 | EF5711151E9615E4007C5BA6 /* LXDGroup.h */, 180 | EF5711161E9615E4007C5BA6 /* LXDGroup.m */, 181 | EF5711171E9615E4007C5BA6 /* LXDQueue.h */, 182 | EF5711181E9615E4007C5BA6 /* LXDQueue.m */, 183 | EF5711191E9615E4007C5BA6 /* LXDSemaphore.h */, 184 | EF57111A1E9615E4007C5BA6 /* LXDSemaphore.m */, 185 | EF57111B1E9615E4007C5BA6 /* LXDTimer.h */, 186 | EF57111C1E9615E4007C5BA6 /* LXDTimer.m */, 187 | ); 188 | path = GCD; 189 | sourceTree = ""; 190 | }; 191 | /* End PBXGroup section */ 192 | 193 | /* Begin PBXNativeTarget section */ 194 | EF5710D51E95CBE8007C5BA6 /* LXDDispatchOperation */ = { 195 | isa = PBXNativeTarget; 196 | buildConfigurationList = EF5711031E95CBE8007C5BA6 /* Build configuration list for PBXNativeTarget "LXDDispatchOperation" */; 197 | buildPhases = ( 198 | EF5710D21E95CBE8007C5BA6 /* Sources */, 199 | EF5710D31E95CBE8007C5BA6 /* Frameworks */, 200 | EF5710D41E95CBE8007C5BA6 /* Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = LXDDispatchOperation; 207 | productName = LXDDispatchOperation; 208 | productReference = EF5710D61E95CBE8007C5BA6 /* LXDDispatchOperation.app */; 209 | productType = "com.apple.product-type.application"; 210 | }; 211 | EF5710EE1E95CBE8007C5BA6 /* LXDDispatchOperationTests */ = { 212 | isa = PBXNativeTarget; 213 | buildConfigurationList = EF5711061E95CBE8007C5BA6 /* Build configuration list for PBXNativeTarget "LXDDispatchOperationTests" */; 214 | buildPhases = ( 215 | EF5710EB1E95CBE8007C5BA6 /* Sources */, 216 | EF5710EC1E95CBE8007C5BA6 /* Frameworks */, 217 | EF5710ED1E95CBE8007C5BA6 /* Resources */, 218 | ); 219 | buildRules = ( 220 | ); 221 | dependencies = ( 222 | EF5710F11E95CBE8007C5BA6 /* PBXTargetDependency */, 223 | ); 224 | name = LXDDispatchOperationTests; 225 | productName = LXDDispatchOperationTests; 226 | productReference = EF5710EF1E95CBE8007C5BA6 /* LXDDispatchOperationTests.xctest */; 227 | productType = "com.apple.product-type.bundle.unit-test"; 228 | }; 229 | EF5710F91E95CBE8007C5BA6 /* LXDDispatchOperationUITests */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = EF5711091E95CBE8007C5BA6 /* Build configuration list for PBXNativeTarget "LXDDispatchOperationUITests" */; 232 | buildPhases = ( 233 | EF5710F61E95CBE8007C5BA6 /* Sources */, 234 | EF5710F71E95CBE8007C5BA6 /* Frameworks */, 235 | EF5710F81E95CBE8007C5BA6 /* Resources */, 236 | ); 237 | buildRules = ( 238 | ); 239 | dependencies = ( 240 | EF5710FC1E95CBE8007C5BA6 /* PBXTargetDependency */, 241 | ); 242 | name = LXDDispatchOperationUITests; 243 | productName = LXDDispatchOperationUITests; 244 | productReference = EF5710FA1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.xctest */; 245 | productType = "com.apple.product-type.bundle.ui-testing"; 246 | }; 247 | /* End PBXNativeTarget section */ 248 | 249 | /* Begin PBXProject section */ 250 | EF5710CE1E95CBE8007C5BA6 /* Project object */ = { 251 | isa = PBXProject; 252 | attributes = { 253 | LastUpgradeCheck = 0830; 254 | ORGANIZATIONNAME = Jolimark; 255 | TargetAttributes = { 256 | EF5710D51E95CBE8007C5BA6 = { 257 | CreatedOnToolsVersion = 8.3; 258 | DevelopmentTeam = 7J57ACJ383; 259 | ProvisioningStyle = Automatic; 260 | }; 261 | EF5710EE1E95CBE8007C5BA6 = { 262 | CreatedOnToolsVersion = 8.3; 263 | DevelopmentTeam = 7J57ACJ383; 264 | ProvisioningStyle = Automatic; 265 | TestTargetID = EF5710D51E95CBE8007C5BA6; 266 | }; 267 | EF5710F91E95CBE8007C5BA6 = { 268 | CreatedOnToolsVersion = 8.3; 269 | DevelopmentTeam = 7J57ACJ383; 270 | ProvisioningStyle = Automatic; 271 | TestTargetID = EF5710D51E95CBE8007C5BA6; 272 | }; 273 | }; 274 | }; 275 | buildConfigurationList = EF5710D11E95CBE8007C5BA6 /* Build configuration list for PBXProject "LXDDispatchOperation" */; 276 | compatibilityVersion = "Xcode 3.2"; 277 | developmentRegion = English; 278 | hasScannedForEncodings = 0; 279 | knownRegions = ( 280 | en, 281 | Base, 282 | ); 283 | mainGroup = EF5710CD1E95CBE8007C5BA6; 284 | productRefGroup = EF5710D71E95CBE8007C5BA6 /* Products */; 285 | projectDirPath = ""; 286 | projectRoot = ""; 287 | targets = ( 288 | EF5710D51E95CBE8007C5BA6 /* LXDDispatchOperation */, 289 | EF5710EE1E95CBE8007C5BA6 /* LXDDispatchOperationTests */, 290 | EF5710F91E95CBE8007C5BA6 /* LXDDispatchOperationUITests */, 291 | ); 292 | }; 293 | /* End PBXProject section */ 294 | 295 | /* Begin PBXResourcesBuildPhase section */ 296 | EF5710D41E95CBE8007C5BA6 /* Resources */ = { 297 | isa = PBXResourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | EF5710E91E95CBE8007C5BA6 /* LaunchScreen.storyboard in Resources */, 301 | EF5710E61E95CBE8007C5BA6 /* Assets.xcassets in Resources */, 302 | EF5710E41E95CBE8007C5BA6 /* Main.storyboard in Resources */, 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | EF5710ED1E95CBE8007C5BA6 /* Resources */ = { 307 | isa = PBXResourcesBuildPhase; 308 | buildActionMask = 2147483647; 309 | files = ( 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | EF5710F81E95CBE8007C5BA6 /* Resources */ = { 314 | isa = PBXResourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | ); 318 | runOnlyForDeploymentPostprocessing = 0; 319 | }; 320 | /* End PBXResourcesBuildPhase section */ 321 | 322 | /* Begin PBXSourcesBuildPhase section */ 323 | EF5710D21E95CBE8007C5BA6 /* Sources */ = { 324 | isa = PBXSourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | EF57111E1E9615E4007C5BA6 /* LXDQueue.m in Sources */, 328 | EF5710E11E95CBE8007C5BA6 /* ViewController.m in Sources */, 329 | EF5710DE1E95CBE8007C5BA6 /* AppDelegate.m in Sources */, 330 | EF5710DB1E95CBE8007C5BA6 /* main.m in Sources */, 331 | EF57110F1E95CC07007C5BA6 /* LXDDispatchAsync.m in Sources */, 332 | EF57111F1E9615E4007C5BA6 /* LXDSemaphore.m in Sources */, 333 | EF5711201E9615E4007C5BA6 /* LXDTimer.m in Sources */, 334 | EF57111D1E9615E4007C5BA6 /* LXDGroup.m in Sources */, 335 | EF5711121E95CC63007C5BA6 /* LXDDispatchOperation.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | EF5710EB1E95CBE8007C5BA6 /* Sources */ = { 340 | isa = PBXSourcesBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | EF5710F41E95CBE8007C5BA6 /* LXDDispatchOperationTests.m in Sources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | EF5710F61E95CBE8007C5BA6 /* Sources */ = { 348 | isa = PBXSourcesBuildPhase; 349 | buildActionMask = 2147483647; 350 | files = ( 351 | EF5710FF1E95CBE8007C5BA6 /* LXDDispatchOperationUITests.m in Sources */, 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | /* End PBXSourcesBuildPhase section */ 356 | 357 | /* Begin PBXTargetDependency section */ 358 | EF5710F11E95CBE8007C5BA6 /* PBXTargetDependency */ = { 359 | isa = PBXTargetDependency; 360 | target = EF5710D51E95CBE8007C5BA6 /* LXDDispatchOperation */; 361 | targetProxy = EF5710F01E95CBE8007C5BA6 /* PBXContainerItemProxy */; 362 | }; 363 | EF5710FC1E95CBE8007C5BA6 /* PBXTargetDependency */ = { 364 | isa = PBXTargetDependency; 365 | target = EF5710D51E95CBE8007C5BA6 /* LXDDispatchOperation */; 366 | targetProxy = EF5710FB1E95CBE8007C5BA6 /* PBXContainerItemProxy */; 367 | }; 368 | /* End PBXTargetDependency section */ 369 | 370 | /* Begin PBXVariantGroup section */ 371 | EF5710E21E95CBE8007C5BA6 /* Main.storyboard */ = { 372 | isa = PBXVariantGroup; 373 | children = ( 374 | EF5710E31E95CBE8007C5BA6 /* Base */, 375 | ); 376 | name = Main.storyboard; 377 | sourceTree = ""; 378 | }; 379 | EF5710E71E95CBE8007C5BA6 /* LaunchScreen.storyboard */ = { 380 | isa = PBXVariantGroup; 381 | children = ( 382 | EF5710E81E95CBE8007C5BA6 /* Base */, 383 | ); 384 | name = LaunchScreen.storyboard; 385 | sourceTree = ""; 386 | }; 387 | /* End PBXVariantGroup section */ 388 | 389 | /* Begin XCBuildConfiguration section */ 390 | EF5711011E95CBE8007C5BA6 /* Debug */ = { 391 | isa = XCBuildConfiguration; 392 | buildSettings = { 393 | ALWAYS_SEARCH_USER_PATHS = NO; 394 | CLANG_ANALYZER_NONNULL = YES; 395 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 396 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 397 | CLANG_CXX_LIBRARY = "libc++"; 398 | CLANG_ENABLE_MODULES = YES; 399 | CLANG_ENABLE_OBJC_ARC = YES; 400 | CLANG_WARN_BOOL_CONVERSION = YES; 401 | CLANG_WARN_CONSTANT_CONVERSION = YES; 402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 403 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 404 | CLANG_WARN_EMPTY_BODY = YES; 405 | CLANG_WARN_ENUM_CONVERSION = YES; 406 | CLANG_WARN_INFINITE_RECURSION = YES; 407 | CLANG_WARN_INT_CONVERSION = YES; 408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 409 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 410 | CLANG_WARN_UNREACHABLE_CODE = YES; 411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 413 | COPY_PHASE_STRIP = NO; 414 | DEBUG_INFORMATION_FORMAT = dwarf; 415 | ENABLE_STRICT_OBJC_MSGSEND = YES; 416 | ENABLE_TESTABILITY = YES; 417 | GCC_C_LANGUAGE_STANDARD = gnu99; 418 | GCC_DYNAMIC_NO_PIC = NO; 419 | GCC_NO_COMMON_BLOCKS = YES; 420 | GCC_OPTIMIZATION_LEVEL = 0; 421 | GCC_PREPROCESSOR_DEFINITIONS = ( 422 | "DEBUG=1", 423 | "$(inherited)", 424 | ); 425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 426 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 427 | GCC_WARN_UNDECLARED_SELECTOR = YES; 428 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 429 | GCC_WARN_UNUSED_FUNCTION = YES; 430 | GCC_WARN_UNUSED_VARIABLE = YES; 431 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 432 | MTL_ENABLE_DEBUG_INFO = YES; 433 | ONLY_ACTIVE_ARCH = YES; 434 | SDKROOT = iphoneos; 435 | }; 436 | name = Debug; 437 | }; 438 | EF5711021E95CBE8007C5BA6 /* Release */ = { 439 | isa = XCBuildConfiguration; 440 | buildSettings = { 441 | ALWAYS_SEARCH_USER_PATHS = NO; 442 | CLANG_ANALYZER_NONNULL = YES; 443 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 444 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 445 | CLANG_CXX_LIBRARY = "libc++"; 446 | CLANG_ENABLE_MODULES = YES; 447 | CLANG_ENABLE_OBJC_ARC = YES; 448 | CLANG_WARN_BOOL_CONVERSION = YES; 449 | CLANG_WARN_CONSTANT_CONVERSION = YES; 450 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 451 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INFINITE_RECURSION = YES; 455 | CLANG_WARN_INT_CONVERSION = YES; 456 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 457 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 458 | CLANG_WARN_UNREACHABLE_CODE = YES; 459 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 461 | COPY_PHASE_STRIP = NO; 462 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 463 | ENABLE_NS_ASSERTIONS = NO; 464 | ENABLE_STRICT_OBJC_MSGSEND = YES; 465 | GCC_C_LANGUAGE_STANDARD = gnu99; 466 | GCC_NO_COMMON_BLOCKS = YES; 467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 469 | GCC_WARN_UNDECLARED_SELECTOR = YES; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 474 | MTL_ENABLE_DEBUG_INFO = NO; 475 | SDKROOT = iphoneos; 476 | VALIDATE_PRODUCT = YES; 477 | }; 478 | name = Release; 479 | }; 480 | EF5711041E95CBE8007C5BA6 /* Debug */ = { 481 | isa = XCBuildConfiguration; 482 | buildSettings = { 483 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 484 | DEVELOPMENT_TEAM = 7J57ACJ383; 485 | INFOPLIST_FILE = LXDDispatchOperation/Info.plist; 486 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 488 | PRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDDispatchOperation; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | }; 491 | name = Debug; 492 | }; 493 | EF5711051E95CBE8007C5BA6 /* Release */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 497 | DEVELOPMENT_TEAM = 7J57ACJ383; 498 | INFOPLIST_FILE = LXDDispatchOperation/Info.plist; 499 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 500 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 501 | PRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDDispatchOperation; 502 | PRODUCT_NAME = "$(TARGET_NAME)"; 503 | }; 504 | name = Release; 505 | }; 506 | EF5711071E95CBE8007C5BA6 /* Debug */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | BUNDLE_LOADER = "$(TEST_HOST)"; 510 | DEVELOPMENT_TEAM = 7J57ACJ383; 511 | INFOPLIST_FILE = LXDDispatchOperationTests/Info.plist; 512 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 513 | PRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDDispatchOperationTests; 514 | PRODUCT_NAME = "$(TARGET_NAME)"; 515 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LXDDispatchOperation.app/LXDDispatchOperation"; 516 | }; 517 | name = Debug; 518 | }; 519 | EF5711081E95CBE8007C5BA6 /* Release */ = { 520 | isa = XCBuildConfiguration; 521 | buildSettings = { 522 | BUNDLE_LOADER = "$(TEST_HOST)"; 523 | DEVELOPMENT_TEAM = 7J57ACJ383; 524 | INFOPLIST_FILE = LXDDispatchOperationTests/Info.plist; 525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 526 | PRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDDispatchOperationTests; 527 | PRODUCT_NAME = "$(TARGET_NAME)"; 528 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LXDDispatchOperation.app/LXDDispatchOperation"; 529 | }; 530 | name = Release; 531 | }; 532 | EF57110A1E95CBE8007C5BA6 /* Debug */ = { 533 | isa = XCBuildConfiguration; 534 | buildSettings = { 535 | DEVELOPMENT_TEAM = 7J57ACJ383; 536 | INFOPLIST_FILE = LXDDispatchOperationUITests/Info.plist; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 538 | PRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDDispatchOperationUITests; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | TEST_TARGET_NAME = LXDDispatchOperation; 541 | }; 542 | name = Debug; 543 | }; 544 | EF57110B1E95CBE8007C5BA6 /* Release */ = { 545 | isa = XCBuildConfiguration; 546 | buildSettings = { 547 | DEVELOPMENT_TEAM = 7J57ACJ383; 548 | INFOPLIST_FILE = LXDDispatchOperationUITests/Info.plist; 549 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 550 | PRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDDispatchOperationUITests; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | TEST_TARGET_NAME = LXDDispatchOperation; 553 | }; 554 | name = Release; 555 | }; 556 | /* End XCBuildConfiguration section */ 557 | 558 | /* Begin XCConfigurationList section */ 559 | EF5710D11E95CBE8007C5BA6 /* Build configuration list for PBXProject "LXDDispatchOperation" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | EF5711011E95CBE8007C5BA6 /* Debug */, 563 | EF5711021E95CBE8007C5BA6 /* Release */, 564 | ); 565 | defaultConfigurationIsVisible = 0; 566 | defaultConfigurationName = Release; 567 | }; 568 | EF5711031E95CBE8007C5BA6 /* Build configuration list for PBXNativeTarget "LXDDispatchOperation" */ = { 569 | isa = XCConfigurationList; 570 | buildConfigurations = ( 571 | EF5711041E95CBE8007C5BA6 /* Debug */, 572 | EF5711051E95CBE8007C5BA6 /* Release */, 573 | ); 574 | defaultConfigurationIsVisible = 0; 575 | }; 576 | EF5711061E95CBE8007C5BA6 /* Build configuration list for PBXNativeTarget "LXDDispatchOperationTests" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | EF5711071E95CBE8007C5BA6 /* Debug */, 580 | EF5711081E95CBE8007C5BA6 /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | }; 584 | EF5711091E95CBE8007C5BA6 /* Build configuration list for PBXNativeTarget "LXDDispatchOperationUITests" */ = { 585 | isa = XCConfigurationList; 586 | buildConfigurations = ( 587 | EF57110A1E95CBE8007C5BA6 /* Debug */, 588 | EF57110B1E95CBE8007C5BA6 /* Release */, 589 | ); 590 | defaultConfigurationIsVisible = 0; 591 | }; 592 | /* End XCConfigurationList section */ 593 | }; 594 | rootObject = EF5710CE1E95CBE8007C5BA6 /* Project object */; 595 | } 596 | --------------------------------------------------------------------------------