项目中集成了环信,点击联系客服时需要调取环信的接口,现在有个要求,如果调取环信的登录接口失败了,就要重新登录,但是这个操作不能影响主线程的操作,登录次数达到一定的数量后停止登录。
首先:环信的登录时同步的,需要我们开启一个线程,不然当环信登录失败时会很容易造成界面卡死的情况。
+ (void)loginWithSuccessBlock:(void(^)())success FailureBlock:(void(^)())failure{   // 自己封装的一个公共类

// 开启一个线程防止登录失败时造成主线程卡死

NSOperationQueue *q = [[NSOperationQueue alloc]init];

[q addOperationWithBlock:^{

EMError *error = [[EMClient sharedClient] loginWithUsername:USER_NAME password:@"123456"];

// 主线程更新UI

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

if (!error)

{

[[EMClient sharedClient].options setIsAutoLogin:YES];

success();

}else{

failure();   // 登录失败调取另一个方法继续尝试登录,登录5次停止登录

[[[self alloc] init] HXLoginFailed];

}

}];

}];

}

然后就是登录失败  开启一个线程继续登录,登录5次后停止登录

- (void)HXLoginFailed
{
    [self.thread cancel];
    self.thread = nil;
    NSString* countStr = [SKUserDefaults valueForKey:@"HXCount"];
    if ([countStr intValue]>5) {
        return;
    }
    DLog(@"========%@=====%d",[NSThread currentThread],[countStr intValue]);
    self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(HXLoginFailed2) object:nil];
    [self.thread start];
    self.requestCount++;
}
- (void)HXLoginFailed2
{
    EMError *error = [[EMClient sharedClient] loginWithUsername:USER_NAME password:@"123456"];
    if (error) {
        NSString* countStr = [SKUserDefaults valueForKey:@"HXCount"];
        countStr = [NSString stringWithFormat:@"%d",[countStr intValue]+1];
        [SKUserDefaults setValue:countStr forKey:@"HXCount"];
        [self HXLoginFailed];
    } else {
        
    }
}
------------------------------------------------------------------------华丽分割线---------------------------------------------------------------------------------------------
最后看看NSOperation怎么实现

原理:只要将一个NSOperation(实际开中需要使用其子类NSInvocationOperation、NSBlockOperation)放到NSOperationQueue这个队列中线程就会依次启动。

NSOperation有两个常用子类用于创建线程操作:NSInvocationOperation和NSBlockOperation,两种方式本质没有区别,但是是后者使用Block形式进行代码组织,使用相对方便。
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.OperationQueue = [[NSOperationQueue alloc]init];
        self.OperationQueue.maxConcurrentOperationCount = 1;
    }
    return self;
}

+ (void)loginWithSuccessBlock:(void(^)())success FailureBlock:(void(^)())failure{
    // 开启一个线程防止登录失败时造成主线程卡死
    NSOperationQueue *q = [[NSOperationQueue alloc]init];
    [q addOperationWithBlock:^{
        EMError *error = [[EMClient sharedClient] loginWithUsername:USER_NAME password:@"jimaijie654321"];
        // 主线程更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            if (!error)
            {
                [[EMClient sharedClient].options setIsAutoLogin:YES];
                success();
            }else{
                failure();
                [SKUserDefaults setValue:@"0" forKey:@"HXCount"];
                [[[self alloc] init] HXLoginFailed];
            }
        }];
    }];
}

- (void)HXLoginFailed
{
    NSString* countStr = [SKUserDefaults valueForKey:@"HXCount"];
    if ([countStr intValue]>5) {
        self.OperationQueue = nil;
        return;
    }
    DLog(@"========%@=====%d",[NSThread currentThread],[countStr intValue]);
    [self.OperationQueue addOperationWithBlock:^{
        DLog(@"+++++++++++++%@=====%d",[NSThread currentThread],[countStr intValue]);
        EMError *error = [[EMClient sharedClient] loginWithUsername:USER_NAME password:@"jimaijie654321"];
        // 主线程更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            if (!error)
            {
                [[EMClient sharedClient].options setIsAutoLogin:YES];
            }else{
                NSString* countStr = [SKUserDefaults valueForKey:@"HXCount"];
                countStr = [NSString stringWithFormat:@"%d",[countStr intValue]+1];
                [SKUserDefaults setValue:countStr forKey:@"HXCount"];
                [self HXLoginFailed];
            }
        }];
    }];

}

转载于:https://www.cnblogs.com/darren-chen/p/6590889.html

线程阻塞问题-功能:环信登录失败后自动登录5次相关推荐

  1. java登录失败三次一小时后再等_Spring Security实现多次登录失败后账户锁定功能...

    在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一 ...

  2. android app 自动登录,Android APP首次登录和之后自动登录流程

    Android APP首次登录和之后自动登录流程 Android APP首次登录和之后自动登录流程 App登陆保存数据流程 App因为要实现自动登陆功能,所以必然要保存一些凭据,所以比较复杂. App ...

  3. 登录Windows后自动注销,原来中了pcidump.sys,scvhost.exe,SoundxVolumns.dll,kav32.exe等

    今天上午,一位同事的电脑出现登录Windows后自动注销的故障,用 WinPE 检查发现c:/windows/system32/userinit.exe丢失,从其它电脑中复制了一个userinit.e ...

  4. [js] 写一个方法实现promise失败后自动重试

    [js] 写一个方法实现promise失败后自动重试 <!DOCTYPE html> <html lang="en"><head><met ...

  5. 如何保证同一个账号同时只能在一个设备登录,账号自动登录

    相信很多人在移动开发中都会遇到这样的需求,当手机端的一个账号已经登录的情况下,限制这个账号在另一个设备上同时登录:账号自动登录.其实要做到这个的方法有很多,在这里我说下目前使用最多的一种方法: 在开发 ...

  6. Windows开机自动登录及取消自动登录的设置

    Win10.Win7.WinXP如何开机自动登录?如何取消开机自动登录? 开机自动登录 开始菜单搜索框输入 "netplwiz" 按回车 或"Win+R"组合键 ...

  7. 5分钟集成即时通讯功能——环信Android版

    下载环信demo (Android) 什么是环信demo 环信demo展示了怎样使用环信SDK快速创建一个完整的类微信聊天APP.展示的功能包括:环信SDK初始化,登录,登出,注册消息接收listen ...

  8. 登录判断_Spring Security之多次登录失败后账户锁定功能的实现

    在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一 ...

  9. mysql 用户 多次登录失败_Spring Security之多次登录失败后账户锁定功能的实现

    在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一 ...

  10. php登录失败后,php – X尝试失败后阻止登录

    在尝试失败后,我试图阻止登录x分钟.我已经计划记录用户登录,所以我想我可以使用相同的数据库来计算阻塞是否需要发生. 我的问题: >使用相同的日志表来运行y次失败尝试阻止的逻辑是否有意义? > ...

最新文章

  1. RandomStringUtils工具类
  2. 如何在MySQL中为多个列指定唯一约束?
  3. Lintcode---统计比给定整数小的数的个数
  4. 警告warning: strncpy specified bound XX equals destination size
  5. PHP制作登录异常ip检测功能实例
  6. leetcode689:Maximum Sum of 3 Non-Overlapping Subarrays
  7. mysql插入性能测试
  8. 02_创建 CA 根证书和秘钥
  9. [个人管理]学习超级搜索术知识点总结
  10. 浏览器HTML5 视频播放
  11. model-based强化学习入门
  12. 根据输入的三角形的三条边a、b、c,如果可以构成三角形,计算并输出该三角形的面积和周长,否则输出“Not a Valid Triangle”。
  13. js页面跳转 URL含中文造成乱码
  14. oracle返回0001错误,ORACLE 异常错误处理
  15. Android开发-安卓手机真机调试配置教程(以小米/红米手机为例)
  16. 计算机专业是朝阳还是夕阳?
  17. java弱签名视为未签名,[java 被视为未签名]QQ幸福签名:你所愿,我终于将你视为平常,连看你一眼都觉得多余。...
  18. mock 数据常用的工具网站
  19. vipkid少儿英语怎么样?孩子学完三个月课程后,结果。。。。。。
  20. RomUtil【Android判断手机ROM,用于判断手机机型】

热门文章

  1. js中Array数组基本方法
  2. 第11章—使用对象关系映射持久化数据—SpringBoot+SpringData+Jpa进行查询修改数据库...
  3. Asterisk 11 chan_sip.c: Failed to authenticate device 看不到IP的问题
  4. VisualVM初次使用BTrace功能方法步骤
  5. Less 官方文档学习笔记
  6. 王者-甄别同一板块强弱股的方法【真假美猴王】
  7. 编译ROS-Academy-for-Beginners
  8. CloseableHttpClient 在使用过程中遇到的问题
  9. SEO市场是在扩大还是缩小 Seoer终于会变成什么?
  10. MVC操作SQL数据库增删改查