{"id":16906513,"url":"https://github.com/rsms/lazydispatch","last_synced_at":"2025-10-19T21:42:31.471Z","repository":{"id":5886817,"uuid":"7104731","full_name":"rsms/LazyDispatch","owner":"rsms","description":"Thin API and concept on top of libdispatch (aka Grand Central Dispatch) for Cocoa Objective-C code.","archived":false,"fork":false,"pushed_at":"2012-12-11T07:17:12.000Z","size":187,"stargazers_count":101,"open_issues_count":0,"forks_count":2,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-15T21:17:05.669Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rsms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-12-11T02:42:54.000Z","updated_at":"2024-06-12T08:48:33.000Z","dependencies_parsed_at":"2022-09-19T15:56:24.096Z","dependency_job_id":null,"html_url":"https://github.com/rsms/LazyDispatch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2FLazyDispatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2FLazyDispatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2FLazyDispatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2FLazyDispatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rsms","download_url":"https://codeload.github.com/rsms/LazyDispatch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244943732,"owners_count":20536290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T18:42:56.953Z","updated_at":"2025-10-19T21:42:26.432Z","avatar_url":"https://github.com/rsms.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lazy dispatcher\n\nA very thin API + concepts on top of libdispatch (aka Grand Central Dispatch) for Cocoa Objective-C code.\n\nI'm a lazy person and so it hurts me when I have to write so much to do such common things as to schedule various blocks of code in various dispatch queues. This little thing lets me write less code with the added bonus of making the result more readable.\n\n### Example\n\nFirst, using vanilla libdispatch:\n\n```objc\ndispatch_queue_t parentQueue = dispatch_get_current_queue();\ndispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n  NSLog(@\"Block #1 on queue '%s' (parentQueue: '%s')\",\n        dispatch_queue_get_label(dispatch_get_current_queue()),\n        dispatch_queue_get_label(parentQueue));\n  \n  dispatch_queue_t parentQueue2 = dispatch_get_current_queue();\n  dispatch_async(dispatch_get_main_queue(), ^{\n    NSLog(@\"Block #2 on queue '%s'\",\n          dispatch_queue_get_label(dispatch_get_current_queue()));\n    \n    dispatch_async(parentQueue2, ^{\n      NSLog(@\"Block #3 on queue '%s'\",\n            dispatch_queue_get_label(dispatch_get_current_queue()));\n      exit(0);\n    });\n  });\n});\n```\n\nNow, with LazyDispatch:\n\n```objc\nsched_background ^(DQueue parentQueue){\n  NSLog(@\"Block #1 on queue '%s' (parentQueue: '%s')\",\n        DQueueID(__queue), DQueueID(parentQueue));\n\n  sched_main ^(DQueue parentQueue){\n    NSLog(@\"Block #2 on queue '%s'\", DQueueID(__queue));\n\n    sched(parentQueue) ^{\n      NSLog(@\"Block #3 on queue '%s'\", DQueueID(__queue));\n    };\n  };\n};\n```\n\n    Block #1 on queue 'com.apple.root.default-priority' (parentQueue: 'com.apple.main-thread')\n    Block #2 on queue 'com.apple.main-thread'\n    Block #3 on queue 'com.apple.root.default-priority'\n\nSee. Way simpler yet same performance as no actual overhead is added. We just rephrased things to be a little more readable.\n\n*Wow! I can haz so much fun nows!*\n\nThere are also timers. We love them timers, don't we?!\n\n```objc\nsched_delay(1, ^{\n  NSLog(@\"Delayed block executed after one second\");\n});\n```\n\nJust like e.g. JavaScript, timers can be cancelled:\n\n```objc\nDTimer timer = sched_interval(13.37, ^{\n  NSLog(@\"Delayed block sez hi\");\n});\n//...\nDTimerStop(timer);\n```\n\n## API\n\n### Types\n\n- `DQueue` — A dispatch queue (alias for `dispatch_queue_t`)\n- `DBlock` — A block (alias for `dispatch_block_t`)\n- `DTimer` — A timer (alias for `dispatch_source_t`)\n\n### Special variables\n\n- `__queue` → `DQueue` — The current queue\n- `__main_queue` → `DQueue` — The main queue\n\n### Keyword expressions\n\n#### `sched_background ^([DQueue parentQueue]) → block`\n\nSchedules a block in the background queue. The block can optionally accept an\nargument which will be the queue from which `sched_background` was called.\nThe result of the expression is the block itself.\n\nUseful for invoking callbacks and returning control to the same queue, e.g:\n\n```objc\n- (void)doSomethingFunkyWithCallback:(DBlock)callback {\n  sched_background ^(DQueue parentQueue){\n    // work work work ...\n    sched(parentQueue) callback;\n  };\n}\n```\n\n#### `sched_main ^([DQueue parentQueue]) → block`\n\nSchedules a block in the main queue. The block can optionally accept an argument\nwhich will be the queue from which `sched_main` was called. The result of the\nexpression is the block itself.\n\n#### `sched(DQueue queue) ^([DQueue parentQueue]) → block`\n\nSchedules a block in a `queue`. The block can optionally accept an argument\nwhich will be the queue from which `sched` was called. The result of the\nexpression is the block itself.\n\n### Functions\n\n#### `const char* DQueueID(DQueue queue)`\n\nAccess the human-readable identifier of `queue` (its \"label\")\n\n#### `DTimer sched_delay(NSTimeInterval delay, ^([DTimer[, DQueue]]))`\n\nSchedule a block in the current queue to execute after `delay` seconds. You can call `DTimerStop` on the `DTimer` object (returned from this function) to cancel a timer before it has triggered.\n\nExample:\n\n```objc\n// Schedule a block to be run after a delay of one second\nsched_delay(1, ^{\n  NSLog(@\"Delayed block triggered\");\n});\n```\n\n#### `DTimer sched_interval(NSTimeInterval interval, ^([DTimer[, DQueue]]))`\n\nSchedule a block in the current queue to be executed every `interval` seconds. You are responsible for calling `DTimerStop(timer)` when the timer is no longer needed.\n\nExample:\n\n```objc\n// Schedule a block to be run every 1.1 seconds\nsched_interval(1.1, ^{\n  NSLog(@\"Perpetual block triggered\");\n});\n```\n\n#### `DTimer sched_timer(DQueue queue, NSTimeInterval delay, NSTimeInterval interval, ^([DTimer[, DQueue]]))`\n\nSchedule a timer on `queue` which starts after `delay` seconds and repeats with `interval`.\n\nIf `interval` has a positive value, the timer repeats every `interval` seconds. In this case you are responsible for stopping the timer by calling `DTimerStop(timer)`. If `interval` is zero or negative, the timer is triggered once and then automatically stopped.\n\nExample:\n\n```objc\n// Start a timer on `fooQueue` after 1.5 seconds, triggering in 3.5 second intervals\nsched_timer(fooQueue, 1.5, 3.5, ^(DTimer timer){\n  NSLog(@\"Timer %@ triggered on foo queue\", timer);\n});\n```\n\n#### `DTimer DTimerCreate(DQueue queue, NSTimeInterval delay, NSTimeInterval interval, ^([DTimer[, DQueue]]))`\n\nLike `sched_timer` but only creates a timer (does not schedule it). You need to call `DTimerResume` in order to schedule the timer.\n\nExample:\n\n```objc\nDTimer timer = DTimerCreate(fooQueue, 1.5, 3.5, ^(DTimer timer){\n  NSLog(@\"Timer %@ triggered on foo queue\", timer);\n});\n// ...\nDTimerResume(timer);\n```\n\n#### `DTimer DTimerResume(DTimer timer)`\n\nSchedule a timer that is not yet scheduled (has been paused by `DTimerPause` or just created by `DTimerCreate`.)\n\nEach call to `DTimerResume` must balance a call to `DTimerPause`, or there will be violent memory violations that will crash all the things. This is a property of libdispatch, trading tolerance of use for efficiency. Note that the timers returned from `sched_delay`, `sched_interval` and `sched_timer` are already resumed.\n\n#### `DTimer DTimerPause(DTimer timer)`\n\nUnschedule a timer that has been scheduled. When pausing a timer and later resuming it, the trigger time does *not* adjust for the time which during the timer was paused.\n\n#### `DTimer DTimerSetInterval(DTimer timer, NSTimeInterval interval)`\n\nModify and reset the interval of a timer.\n\nCalling this function has no effect if the timer source has already been canceled.\n\nExample:\n\n```objc\n// Execute a block five times with 1 second interval, then change the interval to\n// execute the block with 2 seconds interval.\n__block int triggerCount = 0;\nsched_interval(1.0, ^(DTimer timer){\n  NSLog(@\"Perpetual block triggered\");\n  if (++triggerCount == 5) {\n    DTimerSetInterval(timer, 2.0);\n  }\n});\n```\n\n#### `void DTimerStop(DTimer timer)`\n\nCancellation prevents any further invocation of the handler block for the specified timer, but does not interrupt a handler block that is already executing.\n\n\n# MIT License\n\nCopyright (c) 2012 Rasmus Andersson \u003chttp://rsms.me/\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsms%2Flazydispatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frsms%2Flazydispatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsms%2Flazydispatch/lists"}