Giter VIP home page Giter VIP logo

iosmemo's People

Contributors

leesen11 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

iosmemo's Issues

撤销已经push到远程仓库的提交

如果本地需要撤退到需要的版本的话,使用
git reset --hard commitId
查看一下版本号
git log remotes/origin/分支名
提交到远程仓库
git push origin 分支名 --force

使用AFNetworking请求后台的null数据结果为字符串

原因是AFN将返回的结果转换成JSON的时候,将null数据转换成了字符串;
具体的解决方法:
创建一个新的AFJSONResponseSerializer实例对象,并将其removesKeysWithNullValues属性赋为YES;
并将该实例对象赋值给AFHTTPSessionManager的responseSerializer属性

自定义类的对象实现深浅拷贝

我们自定义的类是没有遵守NSCopying协议的,因为在类对象调用copy或者mutableCopy协议的时候会发生崩溃.
浅拷贝: 并不会对对象进行复制,而是指向和目标对象相同的内存地址;
深拷贝:会对对象进行复制,并且指向和目标对象不同的内存地址.

在实现-(id)copyWithZone:(nullable NSZone*)zone方法时,我们可以利用runtime

- (id)copyWithZone:(nullable NSZone *)zone{
    CustomModel *model = [CustomModel allocWithZone:zone];
    unsigned int count = 0;
    objc_property_t *properties = class_copyPropertyList([MBFacilityDetailModel class], &count);
    for (int i = 0; i < count; i++) {
        const char *name = property_getName(properties[i]);
        NSString *propertyName = [NSString stringWithUTF8String:name];
        id propertyValue = [self valueForKey:propertyName];
        [model setValue:propertyValue forKey:propertyName];
    }
    free(properties);
    return model;
}

OC中用于小数点的精确计算的类NSDecimalNumber

当我们从后台获取double类型的数据时,如果小数位有值则显示,没有的话只显示整数位.使用double,float类型是无法满足需求的,但是我们可以使用NSDecimalNumber来满足我们的要求;
NSDecimalNumber是继承自NSNumber, 使用时需要先将double类型的数据封装成字符串,之后使用该字符串来初始化得到一个NSDecimalNumber对象;

NSDecimalNumber的默认行为是向上取整,但是我们可以自定义一个NSDecimalNumberHandler类型的对象来修改默认的行为

修改导航栏的入栈和出栈操作

使用setViewControllers方法来实现页面跳转
当我们对UINavigationcontroller控制器进行Push和Pop操作时,其实是对UINavigationcontroller控制器的子控制器栈ViewControllers进行入栈和出栈操作,有些复杂的页面跳转需求,通过Push和Pop并不能很好实现,有例如我们需要由控制器A跳转到控制器B,B控制器返回时要返回到之前没有创建的控制器C,如果是先Pop再Push,在切换过程中,会显示出控制器A的内容, 不能很好的实现我们的需求,我们可以通过调用setViewControllers 方法来更改UINavigationcontroller的子控制器栈并应用到当前的 UINavigationController来完成页面跳转,具体代码如图所示:
image
转自#知识小集#, https://weibo.com/3951595216/HiHITlV3Q?type=comment#_rnd1563862106647

远程仓库添加忽略文件

忽略文件的添加时机一般都是在创建远程仓库的时候,一起添加忽略文件,之后每次提交的时候会自动将需要忽略的文件给忽略掉。

目前项目中是没有忽略文件的,由于我本地分支使用比较多,习惯于在各个分支之间来回切换,而且,提交的文件我都是有选择性的提交的,而不是一股脑的git add . 所以问题来了,这些无效的,需要被忽略的文件对我的干扰极大,所以我忍无可忍,在项目里添加了忽略文件。不出意外的,这些忽略规则没有起任何作用,因为忽略文件的忽略规则是针对于没有被track的文件,但是那些需要被忽略的文件已经被添加到暂存区了。
所以正确的使用姿势应该是:
首先移除缓存文件
git rm -r --cached . (删除所有的缓存文件)
git add . (将这次修改放到暂存区)
git commit -m "删除缓存文件“ (提交)
其次添加忽略文件
提交完成之后,创建.gitignore文件
将.gitignore文件添加到暂存区

现在我们有了两个需要被推送到远程仓库的提交,使用push命令提交即可。
最后
如果对项目进行了简单的操作的话,仍然出现了不需要的文件的变更,那么直接删除即可,然后再这次变更推送到远程仓库即可。

接下来,我做了一个简单的测试,来确保忽略文件已经发生了作用
从远程仓库新clone一个项目,拉取最新的代码,然后对项目进行简单的修改,比如添加断点
然后使用status命令查看仓库状态。如果没有变更的话,那么就是忽略文件已经生效了

解决远程分支删除之后,本地分支仍存在的问题

当某个远程分支被删除之后,我们通过git branch -a仍然可以看到该远程分支;
通过git remote show origin来查看远程分支的详细信息;
使用git remote prune origin来将远程仓库中已经删除的远程分支从本地中移除

git pull命令中的--allow-unrelated-histories参数

"git merge" used to allow merging two branches that have no common base by default, which led to a brand new history of an existing project created and then get pulled by an unsuspecting maintainer, which allowed an unnecessary parallel history merged into the existing project. The command has been taught not to allow this by default, with an escape hatch --allow-unrelated-histories option to be used in a rare event that merges histories of two projects that started their lives independently.

当我们创建好了一个远程仓库,同时也在本地创建了一个本地仓库, 通过将git remote add origin remote-url将远程仓库和本地仓库关联起来时, 如果使用git pull origin master更新代码会报fatal: refusing to merge unrelated histories错误, 因为git merge默认是将两个没有没有共同根基的分支进行合并的. 通过在pull后面添加参数--allow-unrelated-histories更新成功

检查忽略规则

在添加了忽略文件之后,如果添加了新的文件或者是做了一些修改,但是没有状态变更提示,那么可能是该文件被忽略了,我们可以使用git check-ignore -v 文件 命令来进行检测。
比如想要检测User.swift文件:
git check-ignore -v User.swift

消除拉取代码时生成的“Merge branch 'master' of ..."日志

在开发过程中我们可以多次提交代码,当我们最终拉取远程仓库代码的时候,如果别人已经先于我们推送到了远程仓库,那么我们拉取下来的代码会成一个新的提交,并且生成一个如题的日志。
导致这种问题出现的原因,是因为pull操作是fetch+merge的过程。
我们可以通过git pull --rebase来代替git pull

iOS中的文件操作

- (BOOL)setResourceValue:(id)value forKey:(NSString *)key error:(NSError **)error
如果我们的APP需要存放比较大的文件,但又不希望被系统清理掉,我们就需要把资源保存在Documents目录下,但是我们又不希望该文件被iCloud备份,因此就有了这个方法[URL setResourceValue: [NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error];
NSURLIsExcludedFromBackupKey:不被备份;

category中如何添加基本数据类型,以及为什么使用OBJC_ASSOCIATION_RETAIN

@interface UITableViewCell (FDTemplateLayoutCell)
@property (nonatomic, assign) BOOL fd_isTemplateLayoutCell;
@property (nonatomic, assign) BOOL fd_enforceFrameLayout;
@end

@implementation UITableViewCell (FDTemplateLayoutCell)

- (BOOL)fd_isTemplateLayoutCell
{
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)setFd_isTemplateLayoutCell:(BOOL)isTemplateLayoutCell
{
    objc_setAssociatedObject(self, @selector(fd_isTemplateLayoutCell), @(isTemplateLayoutCell), OBJC_ASSOCIATION_RETAIN);
}

- (BOOL)fd_enforceFrameLayout
{
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)setFd_enforceFrameLayout:(BOOL)enforceFrameLayout
{
    objc_setAssociatedObject(self, @selector(fd_enforceFrameLayout), @(enforceFrameLayout), OBJC_ASSOCIATION_RETAIN);
}

@end

修改自定义dispatch queue的优先级

使用dispatch_queue_create函数生成的dispatch queue不管是serial dispatch queue还是concurrent dispatch queue,都使用与默认优先级global dispatch queue相同执行优先级的线程。但是我们可以使用dispatch_set_target_queue函数来变更生成的dispatch queue的执行优先级

dispatch_queue_t serialDispatchQueue = dispatch_queue_create("com.example.gcd.serialDispatchQueue", NULL);
dispatch_queue_t targetDispatchQueue = dispatch_get_global_queue(DISPATCH_PRIORITY_BACKGROUND, 0);
dispatch_set_target_queue(serialDispatchQueue, targetDispatchQueue);

Git中的合并操作

git merge

简单粗暴,只是会多出一个额外的合并提交
比如:我在dev分支上提交了C3,C4,那么当合并到仍处于C2的master分支时,会多出一个C5的merge提交。

git rebase

假如我们当前在dev分支上,并且想要将我们的提交合并到master分支上(前提是,master分支代码是没有更新的, 如果在我们新建了dev分支之后,有其他开发者在master上发布了更新,那么我们是不能将dev上的改动rebase到master上的,因为master分支是一个共享分支,当我们将远程代码rebase到dev分支上之后,master的更新代码是放到dev的后面的,如果我们在rebase到master上会导致master上有重复的提交记录。)
git rebase master (该命令会找到dev和master最近的一个共同祖先提交,然后对比dev上的历次提交,提取相应的修改,并且存为临时文件(保存在.git/rebase目录下),然后指向master分支的基底,并将之前的临时文件的修改依序应用到master分支上)
git checkout master (现在master分支上已经有了dev上的修改,因此我们需要切换到master分支,将这些修改进行合并)
git merge dev (此时master分支只需要快速前进即可)

如果master分支是一个共享分支,其他开发者在上面发布了新的更新,那么我们可以使用rebase将这些更新同步到dev分支,但是开发完成之后,需要将dev上的代码合并到master分支上的时候,不能使用rebase,因为更新代码的时候由于使用了rebase,将master分支上的更新添加到了

提高调用Objective-C方法的速度

在阅读Objective-C高级编程:iOS与OS X多线程和内存管理时看到的一个不错的思路:
GNUstep中的autorelease实际上是用一种特殊的方法来实现的。这种方法能够高效地运行OS X、iOS应用程序中频繁被调用的autorelease方法,它被称为“IMP Caching”。在进行方法调用时,为了解决类名/方法名以及去的方法运行时的函数指针,要在框架初始化时对其结果进行缓存。

id autorelease_class = [NSAutoreleasePool class];
SEL autorelease_sel = @selector(addObject:);
IMP autorelease_imp = [autorelease_class methodForSelector:autorelease_sel];

实际的方法调用就是使用缓存的结果值

- (id)autorelease {
    (*autorelease_imp)(autorelease_class, autorelease_sel, self);
}

这就是IMP Caching的方法调用。虽然同一下源代码完全相同,但从运行效率上看,即使它依赖于运行环境,一般而言速度也是其他方法的2倍。

- (id)autorelease {
    [NSAutoreleasePool addObject:self];
}

忽略文件

在已经存在了一些提交记录的项目里面添加忽略文件可能会导致失败,原因是忽略文件只对untrack的文件起作用,由于之前已经将这些需要被忽略的文件提交了,所以会失败,解决办法是使用以下组合命令:
git rm -r --cached . (删除所有的缓存文件)
git add .
git commit -m "删除本地缓存文件"

对于自定义的Dispatch Queue的内存管理

尽管有ARC这一通过编译器自动管理内存的优秀技术,但生成的Dispatch Queue必须由程序员负责释放。这是因为Dispatch Queue并没有像Block那样具有Objective-C对象来处理的技术。
通过dispatch_queue_create函数生成的Dispatch Queue在使用结束后通过dispatch_release函数释放
dispatch_release(mySerialDispatchQueue);

虽然Concurrent Dispatch Queue是使用多线程执行追加的处理,在dispatch_async函数追加block到Concurrent Dispatch Queue,并立即通过dispatch_release函数进行释放是没有问题的。
在dispatch_async函数中追加block到dispatch queue,该block通过dispatch_retain函数持有dispatch queue。无论dispatch queue 是serial dispatch queue还是concurrent dispatch queue都一样。一旦block执行结束,就通过dispatch_release函数释放该block持有的dispatch queue。

获取UITextField输入的文本

在代理方法- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string里面,通过[textField.text stringByReplacingCharactersInRange:range withString:string];来实时获取用户输入的内容

修改已经提交的commit信息(包括推送到远程仓库的提交信息)

如果在某次提交的时候,不小心输入了错误的信息,可以使用 git commit --amend命令来对信息重新编辑;

如果需要对多条commit信息进行合并的话,使用rebase命令
git rebase -i HEAD~4 (对最近的4次提交进行编辑);
使用pick选取要合并的那次,一般都是最近的这次提交;
使用squash来对其他的提交进行合并

修改已经推送到远程仓库的提交的信息
使用git rebase -i HEAD~4进入对最近四个提交进行编辑;
编辑完成之后使用git commit --amend来修改描述内容
使用git rebase --continue完成变基操作
使用git push origin 远程分支 --force

解析后台返回的时间数据

// 服务器返回的是13位时间戳
NSString *timeStampString = @"1553529600000";

// iOS 生成的时间戳是10位
NSTimeInterval interval =[timeStampString doubleValue] / 1000.0;
NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *dateString = [formatter stringFromDate: date];
NSLog(@"服务器返回的时间戳对应的时间是:%@",dateString);

正确获取图片的文件大小

NSData *imageData = UIImageJPEGRepresentation(image, 0.8); // 0.8是自己多次测试对比得出的一个压缩系数
CGFloat imageKb = imageData / 1000;
CGFloat imageMb = imageKb / 1000;

如果autorelease NSAutoreleasePool对象会如何?

屏幕快照 2019-07-28 13 07 35

通常在使用Objective-C,也就是Foundation框架时,无论调用哪一个对象的autorelease实例方法,实现上是调用的都是NSObject类的autorelease实例方法。但是对于NSAutoreleasePool类,autorelease实例方法已被该类重载,因此运行时就会出错。

卸载Jenkins

//进入以下目录,双击运行
/Library/Application Support/Jenkins/Uninstall.command
//也可以这样运行
sh "/Library/Application Support/Jenkins/Uninstall.command"

Git rebase操作的总结

git rebase是一个有用但是却危险的命令。
我们可以使用git rebase -I HEAD~3来对最近的三次提交进行修改;
我们可以在拉取代码的时候使用git pull --rebase来取代git pull,以免产生多余而无用的合并记录。
git pull --rebase会将本地的提交全部应用到远程提交的后面,看起来像是我们是先更新的代码然后在做出的本地提交
当然我们也可以使用rebase进行代码合并,有几点需要注意的:
我们可以对共享分支使用rebase,但是前提是,在我们检出了dev分支之后并且dev分支没有更新远程仓库的代码,但是由于对rebase分支使用了rebase,那么当我们将本地分支合并到dev分支上之后,必须要删除dev分支,然后在dev分支更新完代码之后在重新检出一个分支;
假设我们在一个共享分支dev分支上进行开发,如果我们又从dev分支上检出了一个feature本地分支来开发,那么当我们切换到dev分支上想要更新代码的时候,必须要先要将feature分支上的代码rebase到dev上,然后再使用pull --rebase来更新远程代码,这样可以很好的避免merge branch...无效日志的产生。

如果dev分支不是共享分支,只有我们自己在上面开发,而master分支是共享分支,那么我们可以使用rebase来将master分支上的代码更新到我们的dev上,最终在将dev分支merge到master分支上面去

判断字符串中是否含有emoji

- (BOOL)stringContainsEmoji:(NSString *)string {
    __block BOOL returnValue = NO;
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
             }

         } else {
             // non surrogate
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
             }
         }
     }];
    
    return returnValue;
}

检查某对象是否被自动release

在非ARC模式下,我们可以通过NSAutoreleasePool类中的调试用非公开的showPools方法来确认已被autorelease的对象的状况,showPools会将现在的NSAutoreleasePool的状况输出到控制台:
[NSAutoreleasePool showPools];
但是NSAutoreleasePool类的showPools类方法只能在iOS中使用,作为替代,在现在的运行时系统中我们使用调试用的非公开函数_objc_autoreleasePoolPrint()

/* 函数声明 */
extern void _objc_autoreleasePoolPrint();
/* autoreleasepool调试用输出开始 */
_objc_autoreleasePoolPrint();

如果运行此函数,就能像下面这样在控制台中确认AutoreleasePool类的情况
屏幕快照 2019-07-28 13 03 09
该函数在检查某对象是否被自动release时非常有用

Cocoapods版本升级

使用### sudo gem install cocoapods即可
如果遇到While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /usr/bin directory.错误的话,使用下面这条命令:
使用sudo gem install cocoapods -n /usr/local/bin

UILabel显示定时器文本的跳动问题解决方案--转自欧阳大哥2013

在iOS9以前系统默认的英文字体是Helvetica, 这种字体每个数字的宽度都是相等的。而在iOS9以后默认的英文字体变为San Fransico字体,这种字体每个数字的宽度是不相等的。
正是因为数字宽度的不相等就导致了用UILabel来显示定时器文本时出现文字跳动闪烁的问题。 因此解决的方案就是选用一种等宽数字字体显示即可。为此有两个解决方案:
用Helvetica字体代码默认字体。

UILabel *label = [UILabel new];
label.font = [UIFont fontWithName:@"Helvetica" size:16];

*用UIFont的新API:+ (UIFont )monospacedDigitSystemFontOfSize:(CGFloat)fontSize weight:(UIFontWeight)weight;

UILabel *label = [UILabel new];
//记得这个API是iOS9以后才有效!!!
label.font = [UIFont monospacedDigitSystemFontOfSize:16 weight:UIFontWeightRegular];  

原文链接: https://juejin.im/post/5d2bd974e51d4556da53d16e

解决导航栏侧滑返回手势和UIScrollView手势冲突

由于在iOS中,默认情况下在同一时刻只能有一个手势被识别,所以当某个界面存在UIScrollView控件并且需要开启导航栏的侧滑手势时,UIScrollView的panGesture会和UINavigationController的interactivePopGestureRecognizer(UIScreenEdgePanGestureRecognizer类实例对象)产生冲突。

最简单粗暴的方式时,遍历获取当前控制器的所有手势,使用
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
这个方法来使UIScrollView的panGesture手势失效。
看一下这个方法的官方文档

// create a relationship with another gesture recognizer that will prevent this gesture's actions from being called until otherGestureRecognizer transitions to UIGestureRecognizerStateFailed
// if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan then this recognizer will instead transition to UIGestureRecognizerStateFailed
// example usage: a single tap may require a double tap to fail

文档解读:这个方法会和另一个手势进行一种联系,当otherGestureRecognizer被调用时,这种联系会阻止当前手势的调用,直到otherGestureRecognizer状态为UIGestureRecognizerStateFailed时,当前手势才会被调用。
如果otherGestureRecognizer状态为UIGestureRecognizerStateRecognized或者UIGestureRecognizerStateBegan时,当前手势的状态会变为UIGestureRecognizerStateFailed

self.navigationController.interactivePopGestureRecognizer.enable = YES;
NSArray *gestureArray = self.navigationController.view.gestureRecognizers;
for (UIGestureRecognizer *gestureRecognizer in gestureArray) {
    if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
        [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer];
    }
}

在项目中使用的时候, 有的界面是可以生效的, 但是有的界面却不生效, 最终将navigationController对象作为interactivePopGestureRecognizer的代理, 然后实现了 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 方法并返回YES. 问题解决

MJRefresh导致的界面上移的问题

当加载了下一页的数据之后,再重新刷新时会导致界面偏移
WeChat3b53568aadcc6ec269e577dad9e91f35
当时使用的是3.1.15.7版本, 原本是以为是版本的原因,但是尝试为tableView的estimateRowHeight属性赋值0之后,问题就消失了

具体的原因查究有待进一步研究

获取引用计数数值的函数

声明如下函数:
uintptr_t _objc_rootRetainCount(id obj);
之后我们可以使用这个函数来查看指定对象的引用计数值
实际上我们并不能够完全信任该函数取得的数值. 对于已经释放的对象以及不正确的对象地址,有时也返回1.另外,在多线程中使用对象的引用计数数值,因为存在竞态条件的问题,所以取得的数值也不一定完全可信.
所以在调试中该函数很有用,但最好在了解其所具有的的问题的基础上来使用

Charles使用总结

使用Charles进行抓包

使用Charles进行本地数据调试
除了使用Charles来抓取网络数据之外,我们还可以对请求进行修改;
breakpoint的使用

map location的使用

我们可以使用save response将接口返回的数据保存到本地,我们可以根据我们的需求做一些响应的修改(比如额外添加几条数据,或者对其中某条数据进行部分修改),我们可以通过map location来将本地数据作为接口的响应数据。
当我们调试完成之后,记得关闭这个请求地址的map location功能,建议使用快捷键Option+Command+L,顺便说一下,关闭map remote功能的快捷键是Option+Command+M

修改终端输出的前缀名称

终端输出的前缀名默认是电脑共享名称 @ 账户名称:文件路径 $
但是我们可以对前缀名进行自定义,方式是对.bash_profile文件进行编辑
export PS1 = "\h: \w $"
显示效果是: 电脑共享名称:文件路径$
其中
\d – Current date
\t – Current time
\h – Host name
# – Command number
\u – User name
\W – Current working directory (ie: Desktop/)
\w – Current working directory with full path (ie: /Users/Admin/Desktop/)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.