####开篇 关于社会化分享,一般用友盟比较多,但是也有其他的实现方式,这里介绍一下 openShare ,可以不利用官方SDK,直接进行分享。和友盟相比包小了太多,不过貌似没法统计,各有特色吧。 ####正文

如上图openShare的整体结构主要分为两大部分,openShare 和各大平台的分类。每个平台都去扩展OpenShare的类方法,来很好的保证平台的增加和整体功能的完善等。 我们通过新浪微博和QQ的登录和分享来介绍openShare的使用以及对源码的实现方法的理解。 ####新浪微博分享 #####AppDelegate配置 首先导入头文件并注册相关的key

 //第一步:注册key[OpenShare connectQQWithAppId:@"1103194207"];[OpenShare connectWeiboWithAppKey:@"402180334"];[OpenShare connectWeixinWithAppId:@"wxd930ea5d5a258f4f"];[OpenShare connectRenrenWithAppId:@"228525" AndAppKey:@"1dd8cba4215d4d4ab96a49d3058c1d7f"];[OpenShare connectAlipay];//支付宝参数都是服务器端生成的,这里不需要key.复制代码

然后设置分享的回调方法代码如下,这里等下分析OpenShare+Weibo文件的时候详细再说。

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{//第二步:添加回调if ([OpenShare handleOpenURL:url]) {return YES;}//这里可以写上其他OpenShare不支持的客户端的回调,比如支付宝等。return YES;
}复制代码

#####ViewController中的调用 在示例代码中登录和分享的调用方法如下:

   UIView *ret=[[UIView alloc] initWithFrame:frame];UIButton *auth=[self button:@"登录" WithCenter:CGPointMake(frame.size.width/2, 40)];[ret addSubview:auth];[auth addEventHandler:^(id sender) {[OpenShare WeiboAuth:@"all" redirectURI:@"http://openshare.gfzj.us/" Success:^(NSDictionary *message) {ULog(@"微博登录成功:\n%@",message);} Fail:^(NSDictionary *message, NSError *error) {ULog(@"微博登录失败:\n%@\n%@",message,error);}];} forControlEvents:UIControlEventTouchUpInside];UIButton *textShare=[self button:@"分享纯文本" WithCenter:CGPointMake(auth.center.x, calcYFrom(auth)+40)];[ret addSubview:textShare];textShare.tag=1001;[textShare addTarget:self action:@selector(weiboViewHandler:) forControlEvents:UIControlEventTouchUpInside];UIButton *imgShare=[self button:@"分享图片" WithCenter:CGPointMake(auth.center.x, calcYFrom(textShare)+40)];[ret addSubview:imgShare];imgShare.tag=1002;[imgShare addTarget:self action:@selector(weiboViewHandler:) forControlEvents:UIControlEventTouchUpInside];UIButton *newsShare=[self button:@"分享新闻" WithCenter:CGPointMake(auth.center.x, calcYFrom(imgShare)+40)];[ret addSubview:newsShare];newsShare.tag=1003;[newsShare addTarget:self action:@selector(weiboViewHandler:) forControlEvents:UIControlEventTouchUpInside];//微博分享的实现方法
-(void)weiboViewHandler:(UIButton*)btn{OSMessage *message=[[OSMessage alloc]init];message.title=@"hello openshare (message.title)";if (btn.tag>=1002) {message.image=testImage;}if (btn.tag==1003) {message.link=@"http://openshare.gfzj.us/";}[OpenShare shareToWeibo:message Success:^(OSMessage *message) {ULog(@"分享到sina微博成功:\%@",message);} Fail:^(OSMessage *message, NSError *error) {ULog(@"分享到sina微博失败:\%@\n%@",message,error);}];
}复制代码

这里首先先说一下登录的事件添加方式

   [auth addEventHandler:^(id sender) {[OpenShare WeiboAuth:@"all" redirectURI:@"http://openshare.gfzj.us/" Success:^(NSDictionary *message) {ULog(@"微博登录成功:\n%@",message);} Fail:^(NSDictionary *message, NSError *error) {ULog(@"微博登录失败:\n%@\n%@",message,error);}];} forControlEvents:UIControlEventTouchUpInside];复制代码

方法的添加是由下图中的UIControl+Blocks文件中实现的

在.h中创建了- (void)addEventHandler:(ActionBlock)handler forControlEvents:(UIControlEvents)controlEvents; 以及ActionBlock。我们点进.m,可以看到主要由两个方法组成代码如下:

- (void)addEventHandler:(ActionBlock)handler forControlEvents:(UIControlEvents)controlEvents
{objc_setAssociatedObject(self, &UIButtonHandlerKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC);[self addTarget:self action:@selector(callActionHandler:) forControlEvents:controlEvents];};
}
- (void)callActionHandler:(id)sender
{ActionBlock handler = (ActionBlock)objc_getAssociatedObject(self, &UIButtonHandlerKey);if (handler) {handler(sender);}
}复制代码

首先

  objc_setAssociatedObject(self, &UIButtonHandlerKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC);
复制代码

为runtime的动态属性的添加,各个参数对应的解释如下

      * @param self  需要添加关联的对象*  @param UIButtonHandlerKey     添加的唯一标识符*  @param handler   关联的对象*  @param OBJC_ASSOCIATION_COPY_NONATOMIC  关联的策略,是个枚举复制代码

这句话可以理解为,以OBJC_ASSOCIATION_COPY_NONATOMIC的关联策略为自己添加一个标识符为UIButtonHandlerKey的handler对象。 点进这句话我们可以看到系统对应的关联策略的枚举,有以下几种形式

    typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {OBJC_ASSOCIATION_ASSIGN = 0,           //< Specifies a weak reference to the associated object.OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //< Specifies a strong reference to the associated object.The association is not made atomically.OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   //< Specifies that the associated object is copied.The association is not made atomically.OBJC_ASSOCIATION_RETAIN = 01401,       //< Specifies a strong reference to the associated object.The association is made atomically.OBJC_ASSOCIATION_COPY = 01403          //< Specifies that the associated object is copied.The association is made atomically.
};
复制代码

OK,接下来在看对应的添加的callActionHandler事件中的代码

ActionBlock handler = (ActionBlock)objc_getAssociatedObject(self, &UIButtonHandlerKey);if (handler) {//判断block是否为null 防止crashhandler(sender);}复制代码

ActionBlock通过标示符UIButtonHandlerKey,得到的之前的管理属性,然后判断如果block不为空,进行下一步的操作。

#####OpenShare+Weibo 我们从调用处着手开始分析一下源码中的一些方法。登录和分享,最先调起的两个方法分别为: 登录

+(void)WeiboAuth:(NSString*)scope redirectURI:(NSString*)redirectURI Success:(authSuccess)success Fail:(authFail)fail;复制代码

分享调起方法

+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;复制代码

点击这两个方法我们首先进入到的是OpenShare+Weibo,一个专门用来处理微博的分类中,我们可以看到一共有以下4个方法:

+(void)connectWeiboWithAppKey:(NSString *)appKey;
+(BOOL)isWeiboInstalled;
/***  分享到微博,微博只支持三种类型:文本/图片/链接。根据OSMessage自动判定想分享的类型。**  @param msg     要分享的msg*  @param success 分享成功回调*  @param fail    分享失败回调*/
+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;/***  微博登录OAuth**  @param scope       scope,如果不填写,默认是all*  @param redirectURI 必须填写,可以通过http://open.weibo.com/apps/402180334/info/advanced编辑(后台不验证,但是必须填写一致)*  @param success     登录成功回调*  @param fail        登录失败回调*/
+(void)WeiboAuth:(NSString*)scope redirectURI:(NSString*)redirectURI Success:(authSuccess)success Fail:(authFail)fail;
复制代码

分别用来注册微博相关的key,判断是否安装以及主要的分享登录。 平台和key的设置

每个分类中设置不同的schema,区分平台
+(void)connectWeiboWithAppKey:(NSString *)appKey{[self set:schema Keys:@{@"appKey":appKey}];
}
调用openShare的设置方法
+(void)set:(NSString*)platform Keys:(NSDictionary *)key{if (!keys) {keys=[[NSMutableDictionary alloc] init];}keys[platform]=key;
}
复制代码
  • 分享的方法 下面通过分享方法,介绍一下核心的分享的实现方式
+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{if (![self beginShare:schema Message:msg Success:success Fail:fail]) {return;}NSDictionary *message;//根据不同的分享形式 设置不同的字典格式 if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {//text类型分享message= @{@"__class" : @"WBMessageObject",@"text" :msg.title};}else if ([msg isEmpty:@[@"link" ] AndNotEmpty:@[@"title",@"image"] ]) {//图片类型分享message=@{@"__class" : @"WBMessageObject",@"imageObject":@{@"imageData":[self dataWithImage:msg.image]},@"text" : msg.title};}else if ([msg isEmpty:nil AndNotEmpty:@[@"title",@"link" ,@"image"] ]) {//链接类型分享message=@{@"__class" : @"WBMessageObject",@"mediaObject":@{@"__class" : @"WBWebpageObject",@"description": msg.desc?:msg.title,@"objectID" : @"identifier1",@"thumbnailData":msg.thumbnail ? [self dataWithImage:msg.thumbnail] : [self dataWithImage:msg.image  scale:CGSizeMake(100, 100)],    //三目运算@"title": msg.title,@"webpageUrl":msg.link}};}NSString *uuid=[[NSUUID UUID] UUIDString];NSArray *messageData=@[@{@"transferObject":[NSKeyedArchiver archivedDataWithRootObject:@{@"__class" :@"WBSendMessageToWeiboRequest",@"message":message,@"requestID" :uuid,}]},@{@"userInfo":[NSKeyedArchiver archivedDataWithRootObject:@{}]},@{@"app":[NSKeyedArchiver archivedDataWithRootObject:@{ @"appKey" : [self keyFor:schema][@"appKey"],@"bundleID" : [self CFBundleIdentifier]}]}];[UIPasteboard generalPasteboard].items=messageData;[self openURL:[NSString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003013000",uuid]];
}复制代码

通过代码我们可以看到主要步骤为:判断参数是否存在-->设置分享方式 -->设置messageData并归档信息-->把数据放到粘贴板上 -->打开网址( [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]]; 的方式) 下面我们分析是如何设置分享方式的,代码如下:

if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {//text类型分享message= @{@"__class" : @"WBMessageObject",@"text" :msg.title};}
复制代码

msg代表的OSMessage对象包含内容如下:

@interface OSMessage : NSObject
@property NSString* title;
@property NSString* desc;
@property NSString* link;
@property UIImage *image;
@property UIImage *thumbnail;
@property OSMultimediaType multimediaType;
//for 微信
@property NSString* extInfo;
@property NSString* mediaDataUrl;
@property NSString* fileExt;
@property (nonatomic, strong) NSData *file;   /// 微信分享gif/文件
/***  判断emptyValueForKeys的value都是空的,notEmptyValueForKeys的value都不是空的。**  @param emptyValueForKeys    空值的key*  @param notEmptyValueForKeys 非空值的key**  @return YES/NO*/
-(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys;
@end复制代码

OSMessage是用来保存分享的数据信息的对象。可以通过其中包含的内容来进行区分分享的内容类型。而其中:-(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys;介绍如下:

-(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys{@try {if (emptyValueForKeys) {for (NSString *key in emptyValueForKeys) {if ([self valueForKeyPath:key]) {//valueForKeyPath 可以获取OSMessage中相同key的元素return NO;   }}if (notEmptyValueForKeys) {for (NSString *key in notEmptyValueForKeys) {if (![self valueForKey:key]) {//取OSMessage对象里 key对应的内容 如果不存在返回NOreturn NO;}}}return YES;}@catch (NSException *exception) {NSLog(@"isEmpty error:\n %@",exception);return NO;}
}复制代码

方法实现的目的是 判断emptyValueForKeys的value都是空的,notEmptyValueForKeys的value都不是空的。valueForKeyPath判断给定的数组中的内容是否有OSMessage中相同key的元素,如果有的话返回NO,走下一种分享模式。valueForKey判断给定的内容是否也存在于OSMessage的对象中,如果存在返回YES。 对下面代码中的翻译为:

 if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {//text类型分享message= @{@"__class" : @"WBMessageObject",@"text" :msg.title};}
复制代码

如果OSMessage对象中不包含,link,image,只包含title,则设置的分享格式是纯文本分享,同时设置分享的字典格式。

    [UIPasteboard generalPasteboard].items=messageData;
复制代码

在新浪微博的分享中以上述方式,把要分享的内容放至剪贴板上。

  • 回调方法

接下来看回调函数

+(BOOL)Weibo_handleOpenURL{
}
复制代码

主要代码如下:

    if ([url.scheme hasPrefix:@"wb"]) {NSArray *items=[UIPasteboard generalPasteboard].items;NSMutableDictionary *ret=[NSMutableDictionary dictionaryWithCapacity:items.count];for (NSDictionary *item in items) {for (NSString *k in item) {ret[k]=[k isEqualToString:@"transferObject"]?[NSKeyedUnarchiver unarchiveObjectWithData:item[k]]:item[k];}}NSDictionary *transferObject=ret[@"transferObject"];if ([transferObject[@"__class"] isEqualToString:@"WBAuthorizeResponse"]) {//通过反归档 取出的类名  登录//authif ([transferObject[@"statusCode"] intValue]==0) {if ([self authSuccessCallback]) {[self authSuccessCallback](transferObject);}}else{if ([self authFailCallback]) {NSError *err=[NSError errorWithDomain:@"weibo_auth_response" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];[self authFailCallback](transferObject,err);}}}else if ([transferObject[@"__class"] isEqualToString:@"WBSendMessageToWeiboResponse"]) {//分享//分享回调if ([transferObject[@"statusCode"] intValue]==0) {if ([self shareSuccessCallback]) {[self shareSuccessCallback]([self message]);}}else{if ([self shareFailCallback]) {NSError *err=[NSError errorWithDomain:@"weibo_share_response" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];[self shareFailCallback]([self message],err);}}}return YES;}
复制代码

主要逻辑为:取出剪贴板上内容 -->根据遍历循环取出-->根据之前设置的字典格式区分内容-->设置回调信息

一次分享的整体流程
  • 01:对应平台设置key 和相关平台设置
+(void)set:(NSString*)platform Keys:(NSDictionary *)key
复制代码
  • 02:对应平台取值方法
+(NSDictionary *)keyFor:(NSString*)platform{return [keys valueForKey:platform]?keys[platform]:nil;
}
复制代码
  • 03:创建创建要分享的OSMessage对象
 OSMessage *message=[[OSMessage alloc]init];
复制代码
  • 04:调去分享微博的方法

  • 05:分享方法的调起内部实现

+(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail
复制代码
  • 06:区分分享方式,设置分享的字典格式,内容以items的形式复制至剪贴板
 [UIPasteboard generalPasteboard].items=messageData;
复制代码
  • 07:拼接uuid 打开软件
  [self openURL:[NSString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003013000",uuid]];
复制代码
  • 08 走OpenShare中回调的hook方法确定是否有回调
+(BOOL)handleOpenURL:(NSURL*)openUrl{
}
复制代码
  • 09分享结束回调,取出剪贴板的数据,做回调处理
实现原理
  • A程序通过Uri跳转到对应的分享程序B里。
  • 在B里面,他读取从粘贴板里的数据和根据uri做对应的分享处理。
  • 分享完,B把分享的状态结果也放到粘贴板里。然后,根据A之前设好的uri,又跳回到A应用中。
  • 然后A把粘贴板的数据读出来,就知道分享是成功还是失败了。

#####hook方法

+(BOOL)handleOpenURL:(NSURL*)openUrl{returnedURL=openUrl;for (NSString *key in keys) {SEL sel=NSSelectorFromString([key stringByAppendingString:@"_handleOpenURL"]);if ([self respondsToSelector:sel]) {NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:sel]];[invocation setSelector:sel];  [invocation setTarget:self];[invocation invoke];  BOOL returnValue;[invocation getReturnValue:&returnValue];if (returnValue) {return YES;}}else{NSLog(@"fatal error: %@ is should have a method: %@",key,[key stringByAppendingString:@"_handleOpenURL"]);}}return NO;
}复制代码

我们主要看一下下面这个方法中的内容

+(BOOL)handleOpenURL:(NSURL*)openUrl{  }
复制代码

创建了一个SEL对象,来获取之前分类中不同的handleOpenURL方法,通过NSSelectorFromString 来判断 未实现的方法是不是我们想要动态添加的方法如:

+(BOOL)Weibo_handleOpenURL{}
复制代码

如果实现了,利用NSInvocation来直接调用这个消息,在设置万签名,和设置对象之后,执行[invocation invoke],然后根据Weibo_handleOpenURL方法中的返回内容通过getReturnValue来确定有无回调方法。

  • NSInvocation介绍 NSInvocation对象只能使用其类方法来初始化,不可使用alloc/init方法。它执行调用之前,需要设置两个方法:setSelector: 和setArgument:atIndex,简单的NSInvocation使用方法如下:
  SEL   selector = @selector(Test2);methodSign = [[self class] instanceMethodSignatureForSelector:selector];NSInvocation *mehtod2Invocation = [NSInvocation invocationWithMethodSignature:methodSign];[mehtod2Invocation setSelector:selector];[mehtod2Invocation invokeWithTarget:self];BOOL returnValue = 1;[mehtod2Invocation getReturnValue:&returnValue];NSLog(@"返回值:%ld",returnValue);-(BOOL)Test2{return NO;
}复制代码

有返回值无参数类型的函数,此处的打印数值应该是0,因为Test2的返回值是NO。

   //有返回值,有参数SEL  selector = @selector(Test3:);NSMethodSignature *method3Sign = [[self class] instanceMethodSignatureForSelector:selector];NSInvocation *method3Invocation = [NSInvocation invocationWithMethodSignature:method3Sign];[method3Invocation setTarget: self];[method3Invocation setSelector:selector];NSString *arg1 = @"testArg1";[method3Invocation setArgument:&arg1 atIndex:2];[method3Invocation invoke];//    [method3Invocation setReturnValue:&arg1];[method3Invocation getReturnValue:&arg1];NSLog(@".....%@",arg1);-(NSString *)Test3 :(NSString*)a{a= @"122334";NSLog(@"----%@",a);return a;
}复制代码

如果是 [method3Invocation getReturnValue:&arg1] 他的作用是获取函数的返回结果,打印结果为

2017-06-22 16:14:40.850 01234567899[2884:103358] ----122334
2017-06-22 16:14:40.850 01234567899[2884:103358] .....122334复制代码

如果是 [method3Invocation setReturnValue:&arg1] 他的作用是设置函数的返回结果 函数表达式变为如下:

-(NSString *)Test3 :(NSString*)a{NSLog(@"----%@",a);return a;
}
复制代码

打印结果为

2017-06-22 16:17:28.261 01234567899[2924:105348] ----testArg1
2017-06-22 16:17:28.261 01234567899[2924:105348] .....testArg1
复制代码

[invocation invoke]; 这个方法中,只要调用invocation的invoke方法,就代表需要执行NSInvocation对象中制定对象的指定方法,并且传递指定的参数。 至此我们基本说完了新浪微博分享的整体流程那么我们在大致说一下QQ分享的时候,与新浪微博的区别。 ####QQ分享的区别 调用分享的主要函数举例如下:

+(void)shareToQQFriends:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{if ([self beginShare:schema Message:msg Success:success Fail:fail]) {[self openURL:[self genShareUrl:msg to:0]];}
}
复制代码

主要的区别在genShareUrl中

+(NSString*)genShareUrl:(OSMessage*)msg to:(int)shareTo{ }
复制代码

数据的归档并放置到剪贴板的方法为[[UIPasteboard generalPasteboard] setData:data forPasteboardType:key];不同于新浪微博的 [UIPasteboard generalPasteboard].items=messageData;具体实现如下:

/**数据的归档 并放置剪贴板*/
+(void)setGeneralPasteboard:(NSString*)key Value:(NSDictionary*)value encoding:(OSPboardEncoding)encoding{if (value&&key) {NSData *data=nil;NSError *err;switch (encoding) {case OSPboardEncodingKeyedArchiver://归档方式存储data=[NSKeyedArchiver archivedDataWithRootObject:value];break;case OSPboardEncodingPropertyListSerialization://序列化data=[NSPropertyListSerialization dataWithPropertyList:value format:NSPropertyListBinaryFormat_v1_0 options:0 error:&err];default:NSLog(@"encoding not implemented");break;}if (err) {NSLog(@"error when NSPropertyListSerialization: %@",err);}else if (data){[[UIPasteboard generalPasteboard] setData:data forPasteboardType:key];///*data类型的数据放在粘贴板中,pasteboardType  类型 字符串*/}}
}/**从剪贴板取出数据  并解档*/
+(NSDictionary*)generalPasteboardData:(NSString*)key encoding:(OSPboardEncoding)encoding{NSData *data=[[UIPasteboard generalPasteboard] dataForPasteboardType:key];//从剪贴板取出数据NSDictionary *dic=nil;if (data) {NSError *err;switch (encoding) {case OSPboardEncodingKeyedArchiver:dic= [NSKeyedUnarchiver unarchiveObjectWithData:data];break;case OSPboardEncodingPropertyListSerialization:dic=[NSPropertyListSerialization propertyListWithData:data options:0 format:0 error:&err];default:break;}if (err) {NSLog(@"error when NSPropertyListSerialization: %@",err);}}return dic;
}复制代码

并在打开软件的过程中使用了base64编码等,其余的原理大致相同。 到这里,对openShare实现的过程和源码有了大致的说明,可以开心的使用啦。

####后记 这篇介绍,主要是自己对openShare,实现的一种认识,以及对源码的理解,可能存在一定的错误和理解偏差,希望积极指出。

轻量级社会化分享openShare源码解析相关推荐

  1. 技术分享 | AlertManager 源码解析

    作者:石蓓蓓 爱可生研发工程师,主要负责爱可生产品云DMP树产品的研发工作. 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源. AlertManage ...

  2. 轻量级Rpc框架设计--motan源码解析六:client端服务发现

    一, Client端初始化工作 client端通过RefererConfigBean类实现InitializingBean接口的afterPropertiesSet方法, 进行下面三项检查配置工作: ...

  3. iOS开发之Masonry框架源码解析

    Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...

  4. openGauss数据库源码解析系列文章--openGauss简介(一)

    openGauss数据库是华为深度融合在数据库领域多年经验,结合企业级场景要求推出的新一代企业级开源数据库.此前,Gauss松鼠会已经发布了openGauss数据库核心技术系列文章,介绍了openGa ...

  5. VVeboTableView 源码解析

    原文链接:http://www.jianshu.com/p/78027a3a2c41 最近在看一些 iOS 性能优化的文章,我找到了 VVeboTableView 这个框架.严格来说这个不属于框架,而 ...

  6. 【vuejs深入三】vue源码解析之二 htmlParse解析器的实现

    写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 昨天博主分析了一下在vue中,最为基础核心的api,parse函数,它的作用是将vue的模板字符串转换成ast,从而 ...

  7. 注册中心 Eureka 源码解析 —— 应用实例注册发现(五)之过期

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-evict/ ...

  8. Laravel5.2之Filesystem源码解析(下)

    2019独角兽企业重金招聘Python工程师标准>>> 说明:本文主要学习下\League\Flysystem这个Filesystem Abstract Layer,学习下这个pac ...

  9. ConcurrentHashMap源码解析(1)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 注:在看这篇文章之前,如果对HashMap的层不清楚的话,建议先去看看HashMap源码解析. http:/ ...

最新文章

  1. 阿里云Redis账号
  2. pmp考试用计算机,PMP是计算机类考试吗
  3. 初学微信小程序 TodoList
  4. Android旋转切换条目,Android:当我添加动态新的ListView条目时,ListView中的旋转器会丢失它们的值...
  5. ITK:向索引添加偏移量
  6. java实现聊天室界面javafx_java 聊天室WeChat
  7. python中定义变量为啥要用下划线_关于python中带下划线的变量和函数 的意义
  8. 前端笔记-分享一个web后台登录及注册页面
  9. python类详解_python面向对象编程:python类和实例讲解
  10. python类的实例方法必须创建对象后_Python3 类方法,实例方法,静态方法详解...
  11. 海量数据库解决方案2011022101
  12. 《ASCE1885的源码分析》の简单的进程封装类
  13. hbase 预写日志_HDInsight HBase 加速写入现已正式发布
  14. python整型为空的情况_深度剖析凭什么python中整型不会溢出
  15. 支付宝手机网站支付详细流程
  16. 第二十四篇:SuperSpeed/HighSpeed USB的ISO传输
  17. PDF文件如何提取页面,PDF提取页面的小技巧
  18. 人工智能与复杂网络_为什么我与智能手机的关系变得复杂
  19. USB Type-C引脚解析 CC、DFP、UFP、DRP用途解析
  20. 根据日期获取生肖,根据日期获取星座

热门文章

  1. python全栈开发总结_python全栈开发 * 12 知识点汇总 * 180530
  2. php取指定长度,php截取指定长度的简单示例
  3. npm 删除依赖包_前端开发,npm会了吗?
  4. java 注解_怎样理解 Java 注解和运用注解编程?
  5. 全球及中国彩超市场销售渠道与投资竞争力研究报告2022版
  6. 全球及中国商业座机电话行业投资潜力及竞争格局展望报告2021-2027年版
  7. web.xml文件中的web-app元素
  8. Go 面向对象三大特性
  9. 比较强得一个个性签名
  10. 基于墨刀的软件界面原型设计——小说搜索阅读软件