失护委


  • 首页

  • 归档

  • 标签

Protocol Buffers - Google的数据交换格式

发表于 2016-04-15   |  

概述

Protocol Buffers是什么呢,Protocol Buffers是一个灵活高效可序列化的数据交换格式,比起传统的XML方式,它更简单,更小巧,更快,更少歧义,并且能很方便的生成访问数据的类,不需要额外的解析器。

Protocol Buffers源代码

Protocol Buffers的源代码在Github上:https://github.com/google/protobuf,目前支持的语言有C++、Java、Python、Objective-C、C#、JavaNano、JavaScript、Ruby、Go、PHP。
Protocol Buffers源代码由两部分组成:
1、Protocol Buffers代码生成器,可以根据数据描述文件(.proto)生成指定语言的的数据模型类。
2、生成的数据模型类序列化与反序列化需要用到的基础依赖代码。

Protocol Buffers代码生成器的安装与使用

如果你是C++使用者,可以按照C++ Installation Instructions安装Protocol Buffers代码生成器,Objective-c使用者则可以直接下载一个pre-built binary: protobuf-objectivec-3.0.0-beta-2.tar.gz,下载好了之后使用如下命令安装:

1
2
3
4
5
6
tar -xzvf protobuf-objectivec-3.0.0-beta-2.tar.gz 
cd protobuf-3.0.0-beta-2
./configure
make
make check
sudo make install

安装好生成器之后,可以使用如下命令查看生成器的帮助文档

1
protoc -h

要使用生成器生成代码,需先编写.proto描述文件,示例如下

1
2
3
4
5
6
7
8
9
syntax = "proto3";//默认是生成proto2格式的代码,所以加上了一个proto3的头
message Person {
string name = 1;
int32 sex = 2;
int32 age = 3;
}
message Family {
repeated Person person = 1;//经过repeated修饰,能对应生成数组属性
}

编写好描述文件,保存为Family.proto,cd到同一目录下,执行以下命令

1
protoc --objc_out=./ ./Family.proto

ls以下便可查看到已经生成了一组代码文件

1
2
Family.pbobjc.h
Family.pbobjc.m

改变命令参数–objc_out为–cpp_out、–java_out可以生成对应其他语言使用的代码文件。

Protocol Buffers生成器生成的代码的使用

新建一个工程,将之前生成的代码添加进工程,因为生成的代码是MRC的,所以需要加上-fno-objc-arc这样的Compiler Flag,然后新建一个Podfile文件,编写内容如下

1
2
platform :ios, ‘7.2’
pod "Protobuf", "~> 3.0.0-beta-2"

这里一定记住版本号要和之前的生成器版本号一致,否则无法正常使用。执行pod install命令,重新用.xcworkspace文件打开工程,之后便可以开始使用Protocol Buffers生成器生成的代码啦,示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- (void)viewDidLoad {
[super viewDidLoad];

Person *daddy = [Person new];
daddy.name = @"李雷";
daddy.sex = 1;
daddy.age = 28;

Person *mommy = [Person new];
mommy.name = @"韩梅梅";
mommy.sex = 2;
mommy.age = 26;

Person *daughter = [Person new];
daughter.name = @"李丽丽";
daughter.sex = 2;
daughter.age = 3;

Family *family1 = [Family new];
[family1.personArray addObject:daddy];
[family1.personArray addObject:mommy];
[family1.personArray addObject:daughter];

NSData *data = [family1 data];

[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"Family"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSData *data2 = [[NSUserDefaults standardUserDefaults] objectForKey:@"Family"];

Family *family2 = [Family parseFromData:data2 error:NULL];

for (Person *p in family2.personArray) {
NSLog(@"\n============\n%@\n%d\n%d\n============",p.name,p.sex,p.age);
}
}

更多Protocol Buffers相关内容请参看:https://developers.google.com/protocol-buffers/

Protocol Buffers与JSON

Protocol Buffers的优点很明显,但也有一些缺点,因为传输时是二进制形式,导致对人的可阅读性较差,而对数据的封装也比较单一,也不支持继承等面向对象概念。

而JSON的缺点在于对应的封装数据类写起来太麻烦,要实现序列化则需要对应的数据封装类实现NSCoding协议,更是要写一些无聊的代码,所以在此推荐一个以前写的通过JSON自动生成实现了NSCoding协议的Objective-c类的工具,工具源代码https://github.com/andylee1988/JSONCreatorPlus,为方便使用,生成的代码附带以下方法。

1
2
3
- (id)initWithJson:(NSDictionary *)aDicJson;
- (NSData*)jsonData;
- (NSMutableDictionary*)dictionary;

另附使用NSKeyedArchiver做序列化的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+ (void)store:(id<NSCoding>)aObject to:(NSString*)strKey {
NSMutableData *mData = [[NSMutableData alloc] init];
NSKeyedArchiver *myKeyedArchiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mData];
[myKeyedArchiver encodeObject:aObject];
[myKeyedArchiver finishEncoding];
[[NSUserDefaults standardUserDefaults] setObject:mData forKey:strKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}

+ (id)getObject:(NSString*)strKey {
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:strKey];
if (data) {
NSKeyedUnarchiver *myKeyedUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
id aObject = [myKeyedUnarchiver decodeObject];
return aObject;
}
return nil;
}

swizzlingMethod方法混写示例

发表于 2016-04-13   |  

记得头文件里面#import <objc/runtime.h>

1
2
3
4
5
6
7
8
9
10
11
12
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self swizzlingMethod:@selector(executeQuery:) with:@selector(swizzling_executeQuery:)];
});
}

+ (void)swizzlingMethod:(SEL)selector1 with:(SEL)selector2 {
Method originalMethod = class_getInstanceMethod([self class], selector1);
Method swizzlingMethod = class_getInstanceMethod([self class], selector2);
method_exchangeImplementations(originalMethod, swizzlingMethod);
}

统计代码行数和字符数

发表于 2016-04-11   |  
  • 代码行数:

    find . -exec wc -l {} \+ | tail -n 1

  • 代码字符数:

    find . -exec wc -c {} \+ | tail -n 1

Hello world

发表于 2016-04-11   |  

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

AndyLee1988

AndyLee1988

4 日志
3 标签
© 2016 AndyLee1988
由 Hexo 强力驱动
主题 - NexT.Mist
友情链接:   建均笔记   庹加林的个人博客   艾暄的个人博客