- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { __weak ProductPickerTableViewController *weakSelf = self; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ const char *label = "ru.example.unique.search"; weakSelf.searchDispatchQueue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL); }); dispatch_async(self.searchDispatchQueue, ^{ NSArray *searchProducts = nil; if ([searchText length]) { searchProducts = [self.food productsBySearchPhrase:searchText]; } dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.searchProducts = searchProducts; [weakSelf.tableView reloadData]; }); }); }
// // dispatch_cancelable_block.h // sebastienthiebaud.us // // Created by Sebastien Thiebaud on 4/9/14. // Copyright (c) 2014 Sebastien Thiebaud. All rights reserved. // typedef void(^dispatch_cancelable_block_t)(BOOL cancel); NS_INLINE dispatch_cancelable_block_t dispatch_after_delay(NSTimeInterval delay, dispatch_block_t block) { if (block == nil) { return nil; } // First we have to create a new dispatch_cancelable_block_t and we also need to copy the block given (if you want more explanations about the __block storage type, read this: https://developer.apple.com/library/ios/documentation/cocoa/conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW6 __block dispatch_cancelable_block_t cancelableBlock = nil; __block dispatch_block_t originalBlock = [block copy]; // This block will be executed in NOW() + delay dispatch_cancelable_block_t delayBlock = ^(BOOL cancel){ if (cancel == NO && originalBlock) { originalBlock(); } // We don't want to hold any objects in the memory originalBlock = nil; }; cancelableBlock = [delayBlock copy]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ // We are now in the future (NOW() + delay). It means the block hasn't been canceled so we can execute it if (cancelableBlock) { cancelableBlock(NO); cancelableBlock = nil; } }); return cancelableBlock; } NS_INLINE void cancel_block(dispatch_cancelable_block_t block) { if (block == nil) { return; } block(YES); block = nil; }
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { __weak ProductPickerTableViewController *weakSelf = self; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ static const char *label = "ru.example.unique.search"; weakSelf.searchDispatchQueue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL); }); double searchDelay = 0.1; if (self.searchBlock != nil) { //We cancel the currently scheduled block cancel_block(self.searchBlock); } self.searchBlock = dispatch_after_delay(searchDelay, ^{ //We "enqueue" this block with a certain delay. It will be canceled if the user types faster than the delay, otherwise it will be executed after the specified delay dispatch_async(self.searchDispatchQueue, ^{ NSArray *searchProducts = nil; if ([searchText length]) { searchProducts = [self.food productsBySearchPhrase:searchText]; } dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.searchProducts = searchProducts; [weakSelf.tableView reloadData]; }); }); }); }
Source: https://habr.com/ru/post/306742/
All Articles