2018-10-27 12:42:19 u013983033 阅读数 193

项目开发中经常会用到方法的延时调用,下面列举现有的几种实现方式:

  • 1、performSelector

    2、NSTimer

    3、sleep

    4、GCD

下面对上面的几种进行详细的介绍:

第一个方法 : performSelector
代码:

NSLog(@"延迟之前");
[self performSelector:@selector(performSelectorMa) withObject:self afterDelay:2];
NSLog(@"延迟之后");

- (void)performSelectorMa {
    NSLog(@"延迟了"); 
}

运行结果 :
在这里插入图片描述
同理 对于的全部取消的performSelector延迟方法

 [NSObject cancelPreviousPerformRequestsWithTarget:self];

取消某个方法的延迟

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(perform) object:nil];

第二个方法:NSTimer

延迟方法

timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(timerAfter) userInfo:nil repeats:NO];

取消延迟

 [timer invalidate];//关闭定时器

执行结果 :
在这里插入图片描述

第三个方法:sleep
sleep是NSThread 线程里面的方法:但是这个方法会阻塞线程;使用的时候要视情况而定;
代码实现

 [NSThread sleepForTimeInterval:2];

执行效果 :
在这里插入图片描述

第四个方法:GCD

代码实现 :

/**
     DISPATCH_TIME_NOW 延迟从当前时间开始
 */
__weak typeof (self) weakSelf = self;
int64_t time = 3;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [weakSelf gcdAfter];//防止循环引用
});

运行结果:
在这里插入图片描述
以上就是几种延迟方法的使用;

csdn demo

github demo

2016-03-01 11:19:51 hexingle_ios 阅读数 1974
  1. 说到iOS页面间的跳转,最常用的莫过于push/present这两种;习惯用xib/storyboard的或许还知道segues跳转(无需代码);还有就是UITabBarController和UINavigationController了。

  2. present跳转延迟的问题:点击cell,跳转另一个ViewController
    当点击cell跳转的时候,发现有明显的延迟。或者你再次点击一下才会立即跳转。

  3. 解决方法:由于某种原因,presentViewController里的内容并不会真的马上触发执行,除非有一个主线程事件触发。比如在弹出慢的时候,你随便点击一下屏幕,马上就能弹出来
    只为唤醒主线程
    将跳转放在主线程执行
2016-05-11 21:35:45 hero_wqb 阅读数 600

列举iOS开发中,几种延迟执行的方法:

1. GCD方法:(可设置在主线程还是子线程执行)

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//do something...
});
2. performSelector方法:(必须在主线程)

[self performSelector:@selector(method) withObject:nil afterDelay:1.0f];

3. sleep方法:(主线程、子线程均可,阻塞式执行方式)

[NSThread sleepForTimeInterval:1.0f];
//do something...

4. 定时器,NSTimer方法:(必须在主线程)

[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(method) userInfo:nil repeats:NO];



2016-06-04 16:01:10 jacob_ios 阅读数 1696

需求:在需要执行一个操作后,延迟3秒再次执行该操作的方法,

  • 方法一:
    缺点:连续重复的操作也会被记录执行,会出现停止点击后,该方法连续执行好几次的现象,用户体验差
 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self updatePlayBarStatus];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self updatePlayBarStatus];
    });
  • 方法二:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self updatePlayBarStatus];    
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(updatePlayBarStatus) withObject:nil afterDelay:3];
}
1.performSelector: withObject: afterDelay: 这个方法是单线程的,也就是说只有当前调用此方法的函数执行完毕后,selector方法才会被调用。
2.cancelPreviousPerformRequestsWithTarget 不到后续参数表示取消全部。
2019-07-21 10:16:16 tom_221x 阅读数 346

自从IOS有了手势之后,在全屏的app中,屏幕的4个边缘都会默认触发系统的手势操作,然后才会把事件传递给app处理。首先触发系统的edge手势,在某些app中没有什么问题,比如返回上一级。但在有些app中,比如全屏游戏,就会带来触摸延迟——非常明显,亦或是误触Home回到了主页。

IOS官方给出的解决方案就是,在UIViewController中重载preferredScreenEdgesDeferringSystemGestures属性。有些文章说是函数,但我在IOS12的SDK中看到的是属性,具体如下:

@interface UIViewController (UIScreenEdgesDeferringSystemGestures)

// Override to return a child view controller or nil. If non-nil, that view controller's screen edges deferring system gestures will be used. If nil, self is used. Whenever the return value changes, -setNeedsScreenEdgesDeferringSystemGesturesUpdate should be called.
@property (nonatomic, readonly, nullable) UIViewController *childViewControllerForScreenEdgesDeferringSystemGestures API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

// Controls the application's preferred screen edges deferring system gestures when this view controller is shown. Default is UIRectEdgeNone.
@property (nonatomic, readonly) UIRectEdge preferredScreenEdgesDeferringSystemGestures API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

// This should be called whenever the return values for the view controller's screen edges deferring system gestures have changed.
- (void)setNeedsUpdateOfScreenEdgesDeferringSystemGestures API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

@end

我们可以看到,preferredScreenEdgesDeferringSystemGestures是一个只读属性,返回UIRectEdge对象,其代表屏幕的哪些边缘不需要首先响应系统手势——有上下左右4个边缘可选。

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);

因此,我们只要在UIViewController的子类,重写这个属性,返回不需要首先触发系统边缘手势的UIRectEdge对象即可。如下:

// delay system edge gestures to let app touches can be processed first
override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge {
    return .all; // 延迟屏幕4个边缘的系统手势触发
}
没有更多推荐了,返回首页