Egi*_*gil 725 objective-c grand-central-dispatch ios objective-c-blocks
有没有办法在延迟后调用带有原始参数的块,比如使用performSelector:withObject:afterDelay:但是使用像int/ double/ 这样的参数float?
Rya*_*yan 1167
我想你在找dispatch_after().它要求您的块不接受任何参数,但您可以让块从本地范围捕获这些变量.
int parameter1 = 12;
float parameter2 = 144.1;
// Delay execution of my block for 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
NSLog(@"parameter1: %d parameter2: %f", parameter1, parameter2);
});
Run Code Online (Sandbox Code Playgroud)
更多:https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
Ste*_*ing 493
您可以dispatch_after稍后用来调用块.在Xcode中,开始输入dispatch_after并点击Enter自动完成以下内容:

这是一个以两个浮点数作为"参数"的示例.您不必依赖任何类型的宏,并且代码的意图非常明确:
let time1 = 8.23
let time2 = 3.42
// Delay 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print("Sum of times: \(time1 + time2)")
}
Run Code Online (Sandbox Code Playgroud)
let time1 = 8.23
let time2 = 3.42
// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
println("Sum of times: \(time1 + time2)")
}
Run Code Online (Sandbox Code Playgroud)
CGFloat time1 = 3.49;
CGFloat time2 = 8.13;
// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
CGFloat newTime = time1 + time2;
NSLog(@"New time: %f", newTime);
});
Run Code Online (Sandbox Code Playgroud)
War*_*shi 197
如何使用Xcode内置代码片段库?

Swift更新:
很多投票激励我更新这个答案.
内置的Xcode代码段库dispatch_after仅用于objective-c语言.人们还可以创建自己的自定义代码段的Swift.
在Xcode中写下这个.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(<#delayInSeconds#> * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
<#code to be executed after a specified delay#>
})
Run Code Online (Sandbox Code Playgroud)
在代码片段列表的底部,会有一个名为的新实体My Code Snippet.编辑此标题.当您输入Xcode时输入建议Completion Shortcut.
有关详细信息,请参阅CreatingaCustomCodeSnippet.
拖动此代码并将其放在代码段库区域中.
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(<#delayInSeconds#>)) {
<#code to be executed after a specified delay#>
}
Run Code Online (Sandbox Code Playgroud)
Oli*_*ain 57
扩展了Jaime Cham的答案,我创建了一个NSObject + Blocks类别,如下所示.我觉得这些方法更符合现有的performSelector:NSObject方法
NSObject的+ Blocks.h
#import <Foundation/Foundation.h>
@interface NSObject (Blocks)
- (void)performBlock:(void (^)())block afterDelay:(NSTimeInterval)delay;
@end
Run Code Online (Sandbox Code Playgroud)
NSObject的+ Blocks.m
#import "NSObject+Blocks.h"
@implementation NSObject (Blocks)
- (void)performBlock:(void (^)())block
{
block();
}
- (void)performBlock:(void (^)())block afterDelay:(NSTimeInterval)delay
{
void (^block_)() = [block copy]; // autorelease this if you're not using ARC
[self performSelector:@selector(performBlock:) withObject:block_ afterDelay:delay];
}
@end
Run Code Online (Sandbox Code Playgroud)
并使用如下:
[anyObject performBlock:^{
[anotherObject doYourThings:stuff];
} afterDelay:0.15];
Run Code Online (Sandbox Code Playgroud)
Jai*_*ham 21
也许比通过GCD,在某个类(例如"Util")或者对象上的类别更简单:
+ (void)runBlock:(void (^)())block
{
block();
}
+ (void)runAfterDelay:(CGFloat)delay block:(void (^)())block
{
void (^block_)() = [[block copy] autorelease];
[self performSelector:@selector(runBlock:) withObject:block_ afterDelay:delay];
}
Run Code Online (Sandbox Code Playgroud)
所以使用:
[Util runAfterDelay:2 block:^{
NSLog(@"two seconds later!");
}];
Run Code Online (Sandbox Code Playgroud)
Ant*_*ine 21
对于Swift,我使用该dispatch_after方法创建了一个全局函数,没什么特别的.我更喜欢这个,因为它易读且易于使用:
func performBlock(block:() -> Void, afterDelay delay:NSTimeInterval){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), block)
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下内容:
performBlock({ () -> Void in
// Perform actions
}, afterDelay: 0.3)
Run Code Online (Sandbox Code Playgroud)
Dan*_*ark 16
这是我的2美分= 5种方法;)
我喜欢封装这些细节,并让AppCode告诉我如何完成我的句子.
void dispatch_after_delay(float delayInSeconds, dispatch_queue_t queue, dispatch_block_t block) {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, queue, block);
}
void dispatch_after_delay_on_main_queue(float delayInSeconds, dispatch_block_t block) {
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_after_delay(delayInSeconds, queue, block);
}
void dispatch_async_on_high_priority_queue(dispatch_block_t block) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), block);
}
void dispatch_async_on_background_queue(dispatch_block_t block) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), block);
}
void dispatch_async_on_main_queue(dispatch_block_t block) {
dispatch_async(dispatch_get_main_queue(), block);
}
Run Code Online (Sandbox Code Playgroud)
PerformSelector:WithObject总是接受一个对象,所以为了传递像int/double/float等参数.....你可以使用这样的东西.
// NSNumber是一个对象..
[self performSelector:@selector(setUserAlphaNumber:)
withObject: [NSNumber numberWithFloat: 1.0f]
afterDelay:1.5];
-(void) setUserAlphaNumber: (NSNumber*) number{
[txtUsername setAlpha: [number floatValue] ];
}
Run Code Online (Sandbox Code Playgroud)
同样的方法你可以使用[NSNumber numberWithInt:]等....在接收方法中你可以将数字转换为格式为[number int]或[number double].
dispatch_after函数在给定的时间段之后将块对象调度到调度队列.使用以下代码在2.0秒后执行一些与UI相关的操作.
let delay = 2.0
let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
let mainQueue = dispatch_get_main_queue()
dispatch_after(delayInNanoSeconds, mainQueue, {
print("Some UI related task after delay")
})
Run Code Online (Sandbox Code Playgroud)
在swift 3.0中:
let dispatchTime: DispatchTime = DispatchTime.now() + Double(Int64(2.0 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: {
})
Run Code Online (Sandbox Code Playgroud)
Xcode 10.2 和 Swift 5 及以上
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
// code to execute
})
Run Code Online (Sandbox Code Playgroud)
这是一个方便的助手,可以防止反复拨打恼人的GCD电话:
public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
let dispatchTime = DispatchTime.now() + seconds
dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}
public enum DispatchLevel {
case main, userInteractive, userInitiated, utility, background
var dispatchQueue: DispatchQueue {
switch self {
case .main: return DispatchQueue.main
case .userInteractive: return DispatchQueue.global(qos: .userInteractive)
case .userInitiated: return DispatchQueue.global(qos: .userInitiated)
case .utility: return DispatchQueue.global(qos: .utility)
case .background: return DispatchQueue.global(qos: .background)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您只需将代码延迟到主线程上,如下所示:
delay(bySeconds: 1.5) {
// delayed code
}
Run Code Online (Sandbox Code Playgroud)
如果您想将代码延迟到不同的线程:
delay(bySeconds: 1.5, dispatchLevel: .background) {
// delayed code that will run on background thread
}
Run Code Online (Sandbox Code Playgroud)
如果你更喜欢一个也有一些更方便功能的框架,那么请查看HandySwift.您可以通过Carthage将其添加到项目中,然后使用它与上面的示例完全相同:
import HandySwift
delay(bySeconds: 1.5) {
// delayed code
}
Run Code Online (Sandbox Code Playgroud)
这是Swift 3在延迟后排队工作的方法.
DispatchQueue.main.asyncAfter(
DispatchTime.now() + DispatchTimeInterval.seconds(2)) {
// do work
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
331722 次 |
| 最近记录: |