版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.05.01 |
前言
很多時候我們需要進(jìn)行延遲處理,在ios中延遲方法有很多慰毅,下面就介紹幾種主要的延時方法扎阶,各有優(yōu)缺點(diǎn)婶芭,希望大家能比較使用着饥。
詳情
一宰掉、perform selector方法
ios中關(guān)于這個方法有幾個方法,主要如下:
@interface NSObject (NSDelayedPerforming)
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray<NSRunLoopMode> *)modes;
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;
@end
這個方法有個優(yōu)點(diǎn)就是不會阻塞線程孟害。此方式要求必須在主線程中執(zhí)行挪拟,否則無效,沒有取消的方法谎柄。我們就以第二個方法進(jìn)行舉例吧球切。
1. JJDelayMethodVC.m
#import "JJDelayMethodVC.h"
@interface JJDelayMethodVC ()
@end
@implementation JJDelayMethodVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
//第一種延時函數(shù)
[self delayMethodOne];
}
#pragma mark - Object Private Function
- (void)delayMethodOne
{
NSDate *dateBefore = [NSDate date];
NSLog(@"dateBefore---%@",dateBefore);
[self performSelector:@selector(delayMethodOneAction) withObject:nil afterDelay:2];
}
#pragma mark - Action
- (void)delayMethodOneAction
{
NSDate *dateAfter = [NSDate date];
NSLog(@"dateAfter---%@",dateAfter);
}
@end
我們看輸出。
2017-05-01 22:35:37.231 delayMethod[6783:293524] dateBefore---2017-05-01 14:35:37 +0000
2017-05-01 22:35:39.302 delayMethod[6783:293524] dateAfter---2017-05-01 14:35:39 +0000
可以看見確實(shí)延時了2s捍歪。上面這個方法的object可以傳參鸵钝,然后在執(zhí)行selector的方法中進(jìn)行接收并處理。
二变逃、GCD dispatch_after方法
GCD中dispatch_after方法也可以實(shí)現(xiàn)延遲怠堪。而且不會阻塞線程,效率較高(推薦使用)凰棉,并且可以在參數(shù)中選擇執(zhí)行的線程陌粹,同樣沒有可取消的方法。
#import "JJDelayMethodVC.h"
@interface JJDelayMethodVC ()
@end
@implementation JJDelayMethodVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
//第一種延時函數(shù)
// [self delayMethodOne];
//第二種延時函數(shù) GCD dispatch
[self delayByDispatch];
}
#pragma mark - Object Private Function
- (void)delayByDispatch
{
NSDate *dateBefore = [NSDate date];
NSLog(@"dateBefore---%@",dateBefore);
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(), ^{
NSDate *dateAfter = [NSDate date];
NSLog(@"dateAfter---%@",dateAfter);
});
}
@end
我們看輸出結(jié)果或舞。
2017-05-01 22:53:14.991 delayMethod[6980:303434] dateBefore---2017-05-01 14:53:14 +0000
2017-05-01 22:53:17.992 delayMethod[6980:303434] dateAfter---2017-05-01 14:53:17 +0000
三映凳、UIView動畫實(shí)現(xiàn)延時
??我們都知道UIView可以實(shí)現(xiàn)動畫延遲,延時操作寫在block里面魏宽,這里需要說明的是,block中的代碼對于是支持animation的代碼派桩,才會有延遲效果蚌斩,對于不支持animation的代碼不會有延遲效果。
下面我們看代碼员魏。
#import "JJDelayMethodVC.h"
@interface JJDelayMethodVC ()
@property (nonatomic, strong) UILabel *titleLabel;
@end
@implementation JJDelayMethodVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
titleLabel.backgroundColor = [UIColor orangeColor];
[self.view addSubview:titleLabel];
self.titleLabel = titleLabel;
self.view.backgroundColor = [UIColor lightGrayColor];
//第一種延時函數(shù)
// [self delayMethodOne];
//第二種延時函數(shù) GCD dispatch
// [self delayByDispatch];
//UIView實(shí)現(xiàn)延遲
[self delayByAnimation];
}
#pragma mark - Object Private Function
- (void)delayByAnimation
{
NSDate *dateBefore = [NSDate date];
NSLog(@"dateBefore---%@",dateBefore);
[UIView animateKeyframesWithDuration:0.25 delay:5 options:UIViewKeyframeAnimationOptionLayoutSubviews animations:^{
self.titleLabel.transform = CGAffineTransformMakeTranslation(0, 300);
} completion:^(BOOL finished) {
NSDate *dateAfter = [NSDate date];
NSLog(@"dateAfter---%@",dateAfter);
self.titleLabel.transform = CGAffineTransformIdentity;
}];
}
@end
然后我們看輸出和gif圖撕阎。
2017-05-01 23:08:39.491 delayMethod[7238:313886] dateBefore---2017-05-01 15:08:39 +0000
2017-05-01 23:08:44.816 delayMethod[7238:313886] dateAfter---2017-05-01 15:08:44 +0000
??需要說明的是碌补,UIview動畫延遲是不會阻塞線程的厦章。
四、NSThread sleep方法
??這個方法也可以實(shí)現(xiàn)延時袜啃,其實(shí)就是讓該線程睡眠一段時間群发,所以它一定會阻塞線程,浪費(fèi)資源熟妓,所以一般是不推薦使用的。它沒有取消的方法,可以放在主線程或者子線程中告材,如果一定要用還是建議放在子線程中防止卡頓界面。
#import "JJDelayMethodVC.h"
@interface JJDelayMethodVC ()
@property (nonatomic, strong) UILabel *titleLabel;
@end
@implementation JJDelayMethodVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
titleLabel.backgroundColor = [UIColor orangeColor];
[self.view addSubview:titleLabel];
self.titleLabel = titleLabel;
self.view.backgroundColor = [UIColor lightGrayColor];
//第一種延時函數(shù)
// [self delayMethodOne];
//第二種延時函數(shù) GCD dispatch
// [self delayByDispatch];
//UIView實(shí)現(xiàn)延遲
// [self delayByAnimation];
//第四種 thread sleep方法
[self delayByThreadSleep];
}
#pragma mark - Object Private Function
- (void)delayByThreadSleep
{
NSLog(@"%@",[NSThread currentThread]);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSDate *dateBefore = [NSDate date];
NSLog(@"dateBefore---%@",dateBefore);
[NSThread sleepForTimeInterval:3];
NSDate *dateAfter = [NSDate date];
NSLog(@"dateAfter---%@",dateAfter);
NSLog(@"%@",[NSThread currentThread]);
});
}
@end
看輸出結(jié)果缰猴。
2017-05-01 23:44:20.307 delayMethod[7589:330545] <NSThread: 0x60800007a340>{number = 1, name = main}
2017-05-01 23:44:20.356 delayMethod[7589:330647] dateBefore---2017-05-01 15:44:20 +0000
2017-05-01 23:44:23.432 delayMethod[7589:330647] dateAfter---2017-05-01 15:44:23 +0000
2017-05-01 23:44:23.432 delayMethod[7589:330647] <NSThread: 0x600000264e80>{number = 3, name = (null)}
五疤剑、NSTime 定時器方法
??定時器NSTimer也可以實(shí)現(xiàn)延遲隘膘,是一種非阻塞的執(zhí)行方式。取消的話可以先判斷isInvalidate然后調(diào)用invalidate取消該定時器弯菊。
我們先看代碼。
#import "JJDelayMethodVC.h"
@interface JJDelayMethodVC ()
@property (nonatomic, strong) UILabel *titleLabel;
@end
@implementation JJDelayMethodVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
titleLabel.backgroundColor = [UIColor orangeColor];
[self.view addSubview:titleLabel];
self.titleLabel = titleLabel;
self.view.backgroundColor = [UIColor lightGrayColor];
//第一種延時函數(shù)
// [self delayMethodOne];
//第二種延時函數(shù) GCD dispatch
// [self delayByDispatch];
//UIView實(shí)現(xiàn)延遲
// [self delayByAnimation];
//第四種 thread sleep方法
// [self delayByThreadSleep];
//第五種 timer方法
[self delayByTimer];
}
#pragma mark - Object Private Function
- (void)delayByTimer
{
NSDate *dateBefore = [NSDate date];
NSLog(@"dateBefore---%@",dateBefore);
NSLog(@"%@",[NSThread currentThread]);
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(delayByTimerAction) userInfo:nil repeats:NO];
}
- (void)delayByTimerAction
{
NSDate *dateAfter = [NSDate date];
NSLog(@"dateAfter---%@",dateAfter);
NSLog(@"%@",[NSThread currentThread]);
}
@end
然后我們看輸出結(jié)果。
2017-05-01 23:53:38.677 delayMethod[7704:335921] dateBefore---2017-05-01 15:53:38 +0000
2017-05-01 23:53:38.677 delayMethod[7704:335921] <NSThread: 0x60800006ea00>{number = 1, name = main}
2017-05-01 23:53:41.752 delayMethod[7704:335921] dateAfter---2017-05-01 15:53:41 +0000
2017-05-01 23:53:41.753 delayMethod[7704:335921] <NSThread: 0x60800006ea00>{number = 1, name = main}
我這里沒有取消timer牛曹,大家可以自己加上醇滥。
后記
??時間就這么多了,先寫這么多吧腺办,以后有更好的東西在和大家分享。謝謝大家书妻,晚安躬拢。