当前位置: 首页 > 编程日记 > 正文

iOS-UIButton防止重复点击(三种办法)

目录

  • 使用场景
  • 方法一 设置enableduserInteractionEnabled属性
  • 方法二 借助cancelPreviousPerformRequestsWithTarget:selector:object实现
  • 方法三 通过runtime交换方法实现
  • 注意事项

一 使用场景

在实际应用场景中,有几个业务场景需要控制UIButton响应事件的时间间隔。

  • 1 当点击按钮来执行网络请求时,若请求耗时稍长,用户往往会多次点击。这样,就执行了多次请求,造成资源浪费。
  • 2 在移动终端设备性能较差时,连续点击按钮会执行多次事件(比如push出来多个viewController)。
  • 3 防止暴力点击。

二 方法一

通过UIButtonenabled属性和userInteractionEnabled属性控制按钮是否可点击。此方案在逻辑上比较清晰、易懂,但具体代码书写分散,常常涉及多个地方。

  • 创建按钮
- (void)drawBtn {UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];[btn setTitle:@"按钮点击" forState:UIControlStateNormal];[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];// 按钮不可点击时,文字颜色置灰[btn setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];[btn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];btn.center = self.view.center;[btn addTarget:self action:@selector(tapBtn:) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btn];
}

按钮不可点击时,标题颜色置灰,方便对比

  • 点击事件
- (void)tapBtn:(UIButton *)btn {NSLog(@"按钮点击...");btn.enabled = NO;dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{btn.enabled = YES;});
}

运行结果

1.gif

2019-06-12 23:21:09.039455+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...
2019-06-12 23:21:11.658751+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...
2019-06-12 23:21:14.057510+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...
2019-06-12 23:21:16.254230+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...
2019-06-12 23:21:18.788004+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...
2019-06-12 23:21:21.155584+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...
2019-06-12 23:21:23.389769+0800 AvoidBtnRepeatClick[8102:362250] 按钮点击...

每隔2秒执行一次方法

方法二

通过 NSObject 的两个方法

// 此方法会在连续点击按钮时取消之前的点击事件,从而只执行最后一次点击事件
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument;
// 多长时间后做某件事情
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;

按钮创建还是上面代码

  • 按钮点击事件如下
/** 方法一 */
- (void)tapBtn:(UIButton *)btn {NSLog(@"按钮点击了...");// 此方法会在连续点击按钮时取消之前的点击事件,从而只执行最后一次点击事件[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(buttonClickedAction:) object:btn];// 多长时间后做某件事情[self performSelector:@selector(buttonClickedAction:) withObject:btn afterDelay:2.0];
}- (void)buttonClickedAction:(UIButton *)btn {NSLog(@"真正开始执行业务 - 比如网络请求...");
}
  • 运行结果

1.gif

2019-06-13 09:15:58.935540+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:15:59.284096+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:15:59.760772+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:00.238923+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:00.689305+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:02.689633+0800 AvoidBtnRepeatClick[62321:2927724] 真正开始执行业务 - 比如网络请求...
2019-06-13 09:16:03.479984+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:03.884124+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:04.334930+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:04.776324+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:05.179153+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:07.179512+0800 AvoidBtnRepeatClick[62321:2927724] 真正开始执行业务 - 比如网络请求...
2019-06-13 09:16:08.062850+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:10.064171+0800 AvoidBtnRepeatClick[62321:2927724] 真正开始执行业务 - 比如网络请求...
2019-06-13 09:16:10.947205+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:12.948065+0800 AvoidBtnRepeatClick[62321:2927724] 真正开始执行业务 - 比如网络请求...
2019-06-13 09:16:13.528897+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:13.776711+0800 AvoidBtnRepeatClick[62321:2927724] 按钮点击了...
2019-06-13 09:16:15.777735+0800 AvoidBtnRepeatClick[62321:2927724] 真正开始执行业务 - 比如网络请求...

通过打印结果可知,如果连续点击多次,只会响应最后一次点击事件,并且是在设定的时间间隔后执行,这边设置的时间间隔是 2S。

总结:会出现延时现象,并且需要对大量的UIButton做处理,工作量大,不方便。

方法三

通过Runtime交换UIButton的响应事件方法,从而控制响应事件的时间间隔。

实现步骤如下:

  • 1 创建一个UIButton的分类,使用runtime增加public属性cs_eventIntervalprivate属性cs_eventInvalid
  • 2 在+load方法中使用runtimeUIButton-sendAction:to:forEvent:方法与自定义的cs_sendAction:to:forEvent:方法进行交换
  • 3 使用cs_eventInterval作为控制cs_eventInvalid的计时因子,用cs_eventInvalid控制UIButtonevent事件是否有效。

*代码实现如下

@interface UIButton (Extension)/** 时间间隔 */
@property(nonatomic, assign)NSTimeInterval cs_eventInterval;@end
#import "UIButton+Extension.h"
#import <objc/runtime.h>static char *const kEventIntervalKey = "kEventIntervalKey"; // 时间间隔
static char *const kEventInvalidKey = "kEventInvalidKey";   // 是否失效@interface UIButton()/** 是否失效 - 即不可以点击 */
@property(nonatomic, assign)BOOL cs_eventInvalid;@end@implementation UIButton (Extension)+ (void)load {// 交换方法Method clickMethod = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));Method cs_clickMethod = class_getInstanceMethod(self, @selector(cs_sendAction:to:forEvent:));method_exchangeImplementations(clickMethod, cs_clickMethod);
}#pragma mark - click- (void)cs_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {if (!self.cs_eventInvalid) {self.cs_eventInvalid = YES;[self cs_sendAction:action to:target forEvent:event];[self performSelector:@selector(setCs_eventInvalid:) withObject:@(NO) afterDelay:self.cs_eventInterval];}
}#pragma mark - set | get- (NSTimeInterval)cs_eventInterval {return [objc_getAssociatedObject(self, kEventIntervalKey) doubleValue];
}- (void)setCs_eventInterval:(NSTimeInterval)cs_eventInterval {objc_setAssociatedObject(self, kEventIntervalKey, @(cs_eventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (BOOL)cs_eventInvalid {return [objc_getAssociatedObject(self, kEventInvalidKey) boolValue];
}- (void)setCs_eventInvalid:(BOOL)cs_eventInvalid {objc_setAssociatedObject(self, kEventInvalidKey, @(cs_eventInvalid), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
  • 测试代码如下
/** 方法三 */
- (void)drawExpecialBtn{UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];[btn setTitle:@"按钮点击" forState:UIControlStateNormal];[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];// 按钮不可点击时,文字颜色置灰[btn setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];[btn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];btn.center = self.view.center;[btn addTarget:self action:@selector(tapBtn:) forControlEvents:UIControlEventTouchUpInside];btn.cs_eventInterval = 2.0;[self.view addSubview:btn];
}- (void)tapBtn:(UIButton *)btn {NSLog(@"按钮点击...");
}
  • 运行结果如下

1.gif

2019-06-13 19:18:48.314110+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:18:50.346907+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:18:52.512887+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:18:54.515119+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:18:56.577693+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:18:58.679121+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:19:00.681003+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:19:02.752387+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...
2019-06-13 19:19:04.879559+0800 AvoidBtnRepeatClick[89795:3312038] 按钮点击...

四 注意事项

在方法三中交互UIButtonsendAction:to:forEvent:方法,实际上交互的是UIControlsendAction:to:forEvent:方法,所以在使用·UIControl·或其·子类(比如UISlider)·的·sendAction:to:forEvent:·方法时会引起参数缺失的崩溃。

  • 测试代码如下
/** 注意事项 */
- (void)slideTest {UISlider *slide = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, 200, 59)];[slide addTarget:self action:@selector(tapSlide:) forControlEvents:UIControlEventTouchUpInside];slide.center = self.view.center;[self.view addSubview:slide];
}- (void)tapSlide:(UISlider *)slider {NSLog(@"UISlider点击...");
}

运行结果

image.png

(void *) $0 = 0x0000600002620000
2019-06-13 19:48:22.753320+0800 AvoidBtnRepeatClick[90086:3328087]  INFO: Reveal Server started (Protocol Version 32).
2019-06-13 19:48:26.329630+0800 AvoidBtnRepeatClick[90086:3328087] -[UISlider cs_eventInvalid]: unrecognized selector sent to instance 0x7ffd79c0f4d0
2019-06-13 19:48:26.340542+0800 AvoidBtnRepeatClick[90086:3328087] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UISlider cs_eventInvalid]: unrecognized selector sent to instance 0x7ffd79c0f4d0'
*** First throw call stack:
(0   CoreFoundation                      0x0000000110be26fb __exceptionPreprocess + 3311   libobjc.A.dylib                     0x0000000110186ac5 objc_exception_throw + 482   CoreFoundation                      0x0000000110c00ab4 -[NSObject(NSObject) doesNotRecognizeSelector:] + 1323   UIKitCore                           0x000000011397cc3d -[UIResponder doesNotRecognizeSelector:] + 2874   CoreFoundation                      0x0000000110be7443 ___forwarding___ + 14435   CoreFoundation                      0x0000000110be9238 _CF_forwarding_prep_0 + 1206   AvoidBtnRepeatClick                 0x000000010f8af1cb -[UIButton(Extension) cs_sendAction:to:forEvent:] + 917   UIKitCore                           0x00000001133a7f36 -[UIControl _sendActionsForEvents:withEvent:] + 4508   UIKitCore                           0x00000001133a6eec -[UIControl touchesEnded:withEvent:] + 5839   UIKitCore                           0x000000011398aeee -[UIWindow _sendTouchesForEvent:] + 254710  UIKitCore                           0x000000011398c5d2 -[UIWindow sendEvent:] + 407911  UIKitCore                           0x000000011396ad16 -[UIApplication sendEvent:] + 35612  UIKitCore                           0x0000000113a3b293 __dispatchPreprocessedEventFromEventQueue + 323213  UIKitCore                           0x0000000113a3dbb9 __handleEventQueueInternal + 591114  CoreFoundation                      0x0000000110b49be1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 1715  CoreFoundation                      0x0000000110b49463 __CFRunLoopDoSources0 + 24316  CoreFoundation                      0x0000000110b43b1f __CFRunLoopRun + 123117  CoreFoundation                      0x0000000110b43302 CFRunLoopRunSpecific + 62618  GraphicsServices                    0x00000001190d22fe GSEventRunModal + 6519  UIKitCore                           0x0000000113950ba2 UIApplicationMain + 14020  AvoidBtnRepeatClick                 0x000000010f8af500 main + 11221  libdyld.dylib                       0x00000001124c1541 start + 122  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

注意:因为在UIButton+Extension.m中的+load方法中交换了UIControlsendAction:to:forEvent:方法,所以在使用UIControl或其子类(比如UISlider)sendAction:to:forEvent:方法时会引起参数缺失的崩溃。可以将UIButton+Extension改成UIControl+Extension以避免此问题。



相关文章:

华为诺亚方舟开源预训练模型“哪吒”,4项任务均达到SOTA

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;BERT之后&#xff0c;新的预训练语言模型XLnet、RoBERTa、ERNIE不断推出&#xff0c;这次&#xff0c;华为诺亚方舟实验室开源了基于BERT的中文预训练语言模型NEZHA&#xff08;哪吒&#xff09;&#xff0c;寓意模型能…

音量调节助手(转)

源&#xff1a;音量调节助手 软件名称&#xff1a;音量调节助手 软件功能&#xff1a;通过键盘快捷键快速调节系统主音量 软件版本&#xff1a;V2014 软件作者&#xff1a;易几网络 操作系统&#xff1a;所有WINDOWS版本 开发工具&#xff1a;DELPHI XE …

TorchVision中通过AlexNet网络进行图像分类

TorchVision中给出了AlexNet的pretrained模型&#xff0c;模型存放位置为https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth &#xff0c;可通过models.alexnet函数下载&#xff0c;此函数实现在torchvision/models/alexnet.py中&#xff0c;下载后在Ubuntu上存放…

西湖龙井也上链?是的,以后你喝什么茶我都知道!

什么&#xff1f;区块链还可以帮忙法律取证&#xff1f;是的&#xff01;就是这么牛13&#xff01;区块链存证第一案12月9日&#xff0c;据《新华每日电讯》报道&#xff0c;杭州互联网法院用区块链提升审判效率。报道提到一个案例。2018年4月&#xff0c;杭州一家公司&#xf…

Java Enumeration接口

import java.util.Vector; import java.util.Enumeration; /* * Enumeration接口中定义了一些方法&#xff0c;通过这些方法可以枚举&#xff08;一次获得一个&#xff09;对象集合中的元素。 * 这种传统接口已被迭代器取代&#xff0c;虽然Enumeration 还未被遗弃&#xff0…

Windows Azure Pack与SCVMM标签解析分享

我在SCVMM上做了好CentOS6.5的VM模板镜像&#xff0c;自己部署也是成功的&#xff0c;现在配置WAP的VM云虚拟机角色配置&#xff0c;在SCVMM上我打好了CentOS6.5的标签&#xff0c;可是在创建虚拟机角色配置中&#xff0c;选择的CentOS却无法找到硬盘&#xff0c;这是怎么回事呢…

Linux下C++中可使用的3种Hook方法

Hook即钩子&#xff0c;截获API调用的技术&#xff0c;是将执行流程重定向到你自己的代码&#xff0c;类似于hack。如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数。这里介绍下Linux下C中可使用的3中Hook方法&#xff1a; 1. GNU C库允许你通过指定适当…

Java Properties 类

Properties 继承于 Hashtable.表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。 Properties 类被许多Java类使用。例如&#xff0c;在获取环境变量时它就作为System.getProperties()方法的返回值。 Properties 定义如下实例变量.这个变量持有一个Properties对…

国产数据库年终大盘点

作者 | 马超 编辑 | 胡巍巍出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;去“IOE”这个概念&#xff0c;最早由王坚院士在刚刚加入阿里时提出&#xff0c;其目标是将IBM 的小型机、Oracle数据库、EMC存储设备从阿里的IT体系中去除&#xff0c;代之以自主研发的系…

解密FFmpeg播放track mode控制

上一篇文章(http://www.cnblogs.com/yangdanny/p/4421130.html)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据&#xff0c;根据解出的NALU长度恢复了H264的起始码和AAC的ADTS头&#xff0c;这样一般来说播放是没有问题。本篇文章来谈谈如何实现基于FFmpeg的track mode控制&…

UIButton防止按钮和手势的暴力点击

首先理解下几个概念 1、IMP&#xff1a;它是指向一个方法具体实现的指针&#xff0c;每一个方法都有一个对应的IMP&#xff0c;当你发起一个消息之后&#xff0c;最终它会执行的那段代码&#xff0c;就是由IMP这个函数指针指向了这个方法实现的 2、SEL&#xff1a;方法名称的描…

使用Windows7上的VS Code打开远程机Ubuntu上的文件操作步骤

之前在https://blog.csdn.net/fengbingchun/article/details/118991855 中介绍过在Windows10通过VS Code打开Ubuntu 16.04上的文件或文件夹的操作步骤。Windows7上的操作与Windows10有所不同&#xff0c;这里记录下。 Visual Studio Code Remote - SSH扩展允许你在任何远程机器…

微众银行殷磊:AI+卫星,从上帝视角洞察资产管理|BDTC 2019

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;12月5日-7日&#xff0c;2019中国大数据技术大会&#xff08;BDTC&#xff09;于北京隆重举办&#xff0c;大会已成功举办十二届&#xff0c;是大数据领域极具影响力的行业盛会。本届大会汇聚了学术界、企业界上千位知…

【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线

对于二分出的答案x而言&#xff0c;验证答案等价于将所有边权>x的边赋成1&#xff0c;否则赋成0&#xff0c;然后判断从1到n的最短路是否<K。 #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 1001 #define M 100…

Python3中装饰器@typing.overload的使用

typing.py的源码在&#xff1a;https://github.com/python/cpython/blob/main/Lib/typing.py 。此模块为类型提示(Type Hints)提供运行时支持。这里介绍下typing.overload的使用&#xff0c;从python 3.5版本开始将Typing作为标准库引入。 python3中增加了Function Annotation(…

19年NAACL纪实:自然语言处理的实用性见解 | CSDN博文精选

作者 | Nikita Zhiltsov翻译 | 王威力校对 | 李海明本文为你概述处理不同NLP问题时的具有卓越性能的方法、技术和框架等。计算语言&#xff1a;人类语言技术学会北美分会2019年年会&#xff08;North American Chapter of the Association for Computational Linguistics: Huma…

高并发场景下数据库的常见问题及解决方案

一、分库分表 &#xff08;1&#xff09;为什么要分库分表 随着系统访问量的增加&#xff0c;QPS越来越高&#xff0c;数据库磁盘容量不断增加&#xff0c;一般数据库服务器的QPS在800-1200的时候性能最佳&#xff0c;当超过2000的时候sql就会变得很慢并且很容易被请求打死&a…

典型用户 persona

persona 典型用户 1、姓名&#xff1a;王涛 2、年龄&#xff1a;22 3、收入&#xff1a;基本无收入 4、代表用户在市场上的比例和重要性&#xff1a;王涛为铁道学生。本软件的用户主要是学生和老师&#xff0c;尤其是广大的铁大学子&#xff0c;所以此典型用户的重要性不言而喻…

PyTorch中nn.Module类简介

torch.nn.Module类是所有神经网络模块(modules)的基类&#xff0c;它的实现在torch/nn/modules/module.py中。你的模型也应该继承这个类&#xff0c;主要重载__init__、forward和extra_repr函数。Modules还可以包含其它Modules&#xff0c;从而可以将它们嵌套在树结构中。 只要…

什么是三层交换机、网关、DNS、子网掩码、MAC地址

一、什么是vlan? 二、单臂路由与三层交换机 三、什么是网关 一、什么是网关 二、如何来理解网关 三、网关的ip地址 四、网关是如何实现通信&#xff1f; 五、什么是默认网关&#xff1f; 四、什么是DNS 五、MAC地址 六、子网掩码 很多朋友多次问到什么是网关、dns、子网掩码&…

20行代码发一篇NeurIPS:梯度共享已经不安全了

整理 | 夕颜&#xff0c;Jane出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】12 月 8 日-14 日&#xff0c;NeurIPS 2019 在加拿大温哥华举行&#xff0c;和往常一样&#xff0c;今年大会吸引了数万名专家参会&#xff0c;并展示了计算机领域的最新进展。其中…

关于页面打印window.print()的样式问题

当我们打印网页的时候。有时候会发现。打印出来的。跟网页上看到的样式的差别有点大。这其中可能有的问题是。样式问题。 当调用打印(window.print())方法时。打印机会在网页的样式中查找 media print{}的样式&#xff0c;并适应到要打印的网页中。 所以 如果要打印的页面符合看…

Python3中参数*args和**kwargs介绍

在Python中&#xff0c;我们可以使用两种特殊符号将可变数量的参数传递给函数&#xff1a;*args和**kwargs。你可以使用任何单词代替args和kwargs&#xff0c;但通常做法是使用args和kwargs。 *args允许函数接受任意数量的位置参数(positional arguments)。 **kwargs收集所有未…

4大主流CPU处理器技术架构,不知道就out了!

作者 | 王艺威责编 | 阿秃RISC&#xff08;精简指令集计算机&#xff09;是一种执行较少类型计算机指令的微处理器&#xff0c;起源于80年代的MIPS主机&#xff08;即RISC机&#xff09;&#xff0c;RISC机中采用的微处理器统称RISC处理器。这样一来&#xff0c;它能够以更快的…

grunt-connect-proxy解决开发时跨域问题

最近的项目中前后端是完全分离开发的&#xff0c;前端用grunt管理项目。这样就会导致一个问题&#xff1a;开发时前端调用后台的接口时因为不在一个服务器&#xff0c;所以会出现跨域问题。但是也不能用JSONP或CROS方式实现真正的跨域&#xff0c;因为项目发布时其实是在同一个…

混合推荐系统就是多个推荐系统“大杂烩”吗?

作者丨gongyouliu编辑丨zandy【导读】在本篇文章中&#xff0c;我们会介绍混合推荐系统(Hybrid Recommender Systems)&#xff0c;就是利用多种推荐算法配合起来做推荐&#xff0c;期望避免单个推荐算法存在的问题&#xff0c;最终获得比单个算法更好的推荐效果。本篇文章我们从…

Python3中collections.OrderedDict介绍

Python3中的collections模块实现了特定目标的容器&#xff0c;以提供Python标准内建容器dict、list、set和tuple的替代选择&#xff0c;包括namedtuple、deque、ChainMap、Counter、OrderedDict、defaultdict、UserDict、UserList、UserString。这里介绍下OrderedDict&#xff…

汗!雅虎中国个人空间

今天发现雅虎中国有了个人空间&#xff0c;偷偷试了下&#xff0c;让人失望到极点&#xff0c;几乎没有什么特点&#xff0c;和MSN很相似&#xff0c;空间相册放着好好的Flickr不用&#xff0c;偏偏弄了个很垃圾的相册&#xff0c;还有整合能力也不行。都不知道del.icio.us和Fl…

关于v$process与v$session中process的理解

v$session有个process字段&#xff0c;V$PROCESS有个SPID字段&#xff0c;这两个字段是不是一个意思呢&#xff1f;是不是都代表会话的操作系统进程呢&#xff1f;官方文档上的解释&#xff1a;SPID VARCHAR2(12) Operating system process identifierPROCESS VARCHAR2…

Python3中lambda表达式介绍

Python3中的lambda表达式或lambda函数是匿名函数(anonymous function)&#xff0c;意味着该函数没有名称。def关键字用于在Python3中创建一个普通函数&#xff0c;类似地&#xff0c;lambda关键字用于在Python3中创建匿名函数。 Python3 lambda函数语法&#xff1a; lambda pa…