这是搭建好Octopress写的第一篇博客,搭建过程中遇到了不少麻烦,但最后还是成功搭建出来了,感觉还不错。 还有很多东
西需要琢磨,比如主题、markdown语法、博客写作….总之,需要花时间折腾一下才行。
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..063b0e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Thumbs.db +db.json +*.log +node_modules/ +public/ +.deploy*/ \ No newline at end of file diff --git a/2013/05/12/2013-05-12-first-blog/index.html b/2013/05/12/2013-05-12-first-blog/index.html deleted file mode 100644 index 8533a52..0000000 --- a/2013/05/12/2013-05-12-first-blog/index.html +++ /dev/null @@ -1,256 +0,0 @@ - - -
- - -这是搭建好Octopress写的第一篇博客,搭建过程中遇到了不少麻烦,但最后还是成功搭建出来了,感觉还不错。 还有很多东
西需要琢磨,比如主题、markdown语法、博客写作….总之,需要花时间折腾一下才行。
不知道从什么时候开始IOS的SDK里多了一个叫instancetype的东西,顾名思义返回的就是一个实例对象,所以也没有深究。 但是这玩意和以前的id有什么区别呢,突然比较好奇。 上网查看了下相关的资料,自己也做了下测试,在这里记录一下。
首先一个很重要的区别,id可以作为函数的参数和返回值,而instancetyp则只能作为返回值;
-其他区别,我用简单的话来概括就是:
-如果返回的是instancetype,那么编译器是知道你返回的具体对象是什么类型,当你向这个实例发送不属于这个类的消息时,编译器则会报错。
-
-而id则是向它可以发送任何消息的,所以编译器不会报错,编译能通过
-
-但是有一种特殊情况: 我们知道- (id)init 这个方法返回的是id,但是当你用这个方法生成的实例,向其发送不属于这个类的消息时,编译器也会报错。
-
-这是为什么呢,不是可以向id发送任意消息吗? 原来这是因为编译器默认的初始化方法返回的是instancetype,你看着是id,但编译器实现时就是给你返回的是instancetype! 当我们用类方法返回的id,编译器才会真正的当成id处理。
-###总结
instancetype的出现,可以避免程序在运行时向某个对象发送不是它的消息引起崩溃,因为编译的时候就不让你通过。所以当你返回的对象确定为这个类的实例时,尽量使用instancetpye吧。 比如经常使用的单例模式,则可声明返回的为instancetype。
仅仅是自己的理解,如有不对之处,请大家指正!
###参考文章
instancetype
最近接触到了Mantle这个东西,感觉很不错,在此与各位分享一下。
###前言
在开发的过程中,我们常常会从网络获取数据,而数据通常又为JSON格式。 这时比较常见的做法是把JSON数据转为Model对象,这样我们可以从Model对象的属性读取数据。 但是常常会面临如下一些问题:
每次都要用 -initWithDictionarty:(NSDictionary *)dict 等类似的方法初始化,把JSON数据里的值一个一个的赋值给Modeld对象的属性,深深的感觉到自己在做重复的工作,有木有!
当你需要的某个数据在JSON字典数据里层次很深时,需要不断的使用 [[obj objectForKey:@"key"] objectAtIndex:index] objectForKey:@""]... 这样很长的代码,是不是感觉很不爽!
服务器给你返回的数据不是你期望的,例如:有些时候你需要的是一个NSString类型,但给你的是一个NSNumber。 有时你需要的是一个NSDate类型,但给你的是一个NSString类型,你还不得不去做一些判断,写一些转换的代码。 还有一种严重的情况,由于服务器故障,给你返回了一个NSNull,如果你没有做一些判断处理,那么这时你的程序崩溃的几率很大!
-如何从这个Model对象,再还原成之前的JSON字典数据? 其次,你想把这个Model对象存储下来的话,那么你不得不自己去处理NSCoding协议等一些烦人的问题,又是一些重复工作!
-有没有办法可以很优雅的解决这些问题呢,这就是今天要说的Mantle框架。
-###什么是Mantle?
Mantle是github的工程师们弄出来的东西,github主页在此,
引用如下:
-Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application.
-
###使用
下面就来说一下怎么使用,首先新建一个空的工程,把Mantle的代码下载下来,拖入你的工程。 我建议使用CocoaPods来管理第三方库,反正我就是这样干的,非常简单方便。 浏览一下框架的目录,大概如下图所示:
-居然这么多文件! 不要害怕,我们常用到的就是MTLJSONAdapter和MTLModle而已。 MTLModel是一个抽象类,它帮我们做了很多工作,比如解决前言里提出的一些问题。 我们要建的Model类应该继承于它,此外你的继承类一定还要实现MTLJSONSerializing协议。 MTLJSONAdapter则是帮我们把JSON数据绑定到Model的属性里,当然,你不用担心会出现NSNull的情况,因为转换后它会自动设置成nil;
我们新建一个继承 MTLModel 的类,叫做 TestDataModel。 我们将从这个地址获取测试数据。 现在把想要的数据声明到头文件里
1 |
|
在TestDataModel.m文件里,实现MTLJSONSerializing协议里的+ (NSDictionary *)JSONKeyPathsByPropertyKey 方法。
1 |
|
解释都在注释里。 Model类到此可以用了。 现在我们在AppDelegate.m里,编写相关的测试代码
1 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions |
设置断点到15行,控制台显示如下图:
-
-可以看到所有属性值均已设置好了。 强大吧! 等等…这好像和我们期望的类型不太一样,我们声明的date是一个NSDate型,但这里却是NSNumber。JSON数据里解析出来的就是NSNumber,那要怎么转化为我们期望的NSDate呢? Mantle为我们提供了强大的转换机制。 继续回到TestDataModel.m文件里。添加如下代码:
1 | //TestDataModel.m |
再次运行,控制台结果如下图:
-
-看见了吗,date已经成功转换为NSDate了! 原来,上面的代码是要告知Mantle,赋值时要先进行转换,原始JSON里是一个NSNumber,现在转换为一个NSDate并返回。 其他属性需要转换的都可以这样做,方法命名规则是 属性JSONTransformer,那么在对这个属性进行赋值时就会调用这个方法先进行转换。当JSON数据里有NSNull的类型时,我们不用做任何处理,会自动将该属性置为nil;
那reverseBlock是干什么的呢? 当要把Model转换回JSON数据时,如果设置了返回值,那么会将NSDate转回NSNumber返回JSON数据。 我们可以调用 MTLJSONAdapter的
1 | + (NSDictionary *)JSONDictionaryFromModel:(MTLModel<MTLJSONSerializing> *)model; |
解档时同样简单:
-1 | TestDataModel *unachiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; |
Mantle还可以结合CoreData使用,这里不说了。 至此,Mantle的简单使用就介绍完了! 如有什么不对之处,请各位谅解和指正!
-###原理
-没有深入研究源码,准备抽时间仔细研究一把。 大致看了下,Mantle主要使用了一些Runtime的东西,获取到所有propertiy属性进行绑定。 代码看起来有种不明觉厉的感觉,不得不感叹github上的牛人真多! 想深入研究的同学可以多看下源码!
-###参考文章
- - - -对于 NSInputStream 和 NSOutputStream 一直没怎么搞清楚,今天抽一些时间在此记录一下!
-NSInputStream 与 NSOutputStream 都继承于 NSStream, NSStream 是一个抽象的基类, 规定了Stream共有的一些行为…
- -###什么是Stream
-Stream翻译成为流,它是对我们读写文件的一个抽象。 你可以这样想象,当你读文件和写文件的时候,文件的内容就像水流一样哗哗的
像你流过来或者流给别人,这样岂不是很爽。 而Stream就帮我们做了这样的事情, 实际上,它是把文件的内容,一小段一小段的读出或
写入,来到达这样的效果
###NSStream
-NSStream 是Cocoa平台下对流这个概念的实现类, NSInputStream 和 NSOutputStream 则是它的两个子类,分别对应了读文件和
写文件。
###NSInputStream
-NSInputStream 对应的是读文件,所以要记住它是要将文件的内容读到内存(你声明的一段buffer)里, 下面一段是测试代码
-1 |
|
###NSOutputStream
-NSOutputStream 对应的是写文件,它是要将已存在的内存(buffer)里的数据写入文件, 下面同样一段是测试代码
-1 |
|
NSInputStream 和 NSOutputStream 常用与网络传输中,比如要将一个很大的文件传送给服务器,那么NSInputStream这时候是
很好的选择, 我们可以查看到 NSURLRequest 有一个属性叫HTTPBodyStream, 这时只要设置好一个NSInputStream的实例就可以
了,最大的好处就是可以节省我们很多的内存。
另外要说明的是,NSInputStream 和 NSOutputStream其实是对 CoreFoundation 层对应的CFReadStreamRef 和 CFWriteStreamRef
的高层抽象。在使用CFNetwork时,常常会使用到CFReadStreamRef 与 CFWriteStreamRef。 下面是一段相关代码
1 |
|
在Mac上简单的编译出一个可以在 IOS 上运行的 hello world 程序:
- -写一个简单的hello world程序,保存到桌面或者其他地方
-终端里cd 到刚才保存的路径
-运行命令:
-1 |
|
1 |
|
1 |
|
成功输出 hello world
- - -Toll free briding 是用于 Foundation对象和Core Foundation对象间无缝转换的一种方法。首先,我们来看看下面代码:1
2
3
4
5
6
CFStringRef cfStr = SomeFunctionThatReturnsCFString();
NSUInteger length = [(NSString *)cfStr length];
NSString *nsStr = [self someString];
CFIndex length = CFStringGetLength((CFStringRef)nsStr);
我们可以将一个 CFStringRef 类型的变量通过指针转换为 NSString * 类型, 然后直接当作NSString 使用, 向其发送消息。
同时,我们也可以将 NSString *通过指针转换为 CFStringRef, 即可当作CFStringRef,对于 CFStringRef 申明的C层级的
API 均能使用。这便是官方所说得 Toll free briding。
那么这一切是如何做到的,内部发生了什么?
-###CF 转为 OBJC
首先,我们来看看CF对象是怎样转为OBJC对象的。 这个方向的转换比较简单。 在OBJC的类里,绝大多数能进行bridging的类都是一层抽象封装,叫做类族。如NSString, 我们在得到真正的实例时是它的一个私有子类NSCFString。 而CFStringRef 和 NSCFString 对象具有相同的内存布局, CFStringRef 的前4个字节也是一个 isa 指针
,指向 NSCFString 类。 由OBJC的消息发送机制我们可以知道,这时候,对其发送OBJC的消息,和对OBJC的对应对象发送消息是一模一样的!
###OBJC 转为 CF
还以NSString为列。上面我们说了:CFStringRef 和 NSCFString 对象具有相同的内存布局。 这时候,你可能要说了,既然是
相同的内存布局,直接作指针转换就好了! OBJC对象即可当作CF对象! 可是,有一些情况比较例外。如果我们写了一个类,继承于NSString, 重写了 length 方法。 那么这时候,这个对象则和 CFStringRef 不再具有相同的内存布局,它们的isa指针指向不同的
类了。 但是这种情况我们任然是可以作bridging的。这又是怎么办到的?
CF在他的API里,都做了一个OBJC方法名的映射,如 CFStringGetLength:
1 |
|
CFStringGetLength 映射了 NSString 的 length方法!
CF_OBJC_FUNCDISPATCH0 就是要去判断传进来的str究竟是不是NSCFString,如果是则调用 __CFStrLength 函数返回。
如果不是,则向这个对象发送 length 消息,并返回。 如果我们传入的是自己继承NSString的对象,
那么这时候则会向这个对象发送length消息,重写的方法就得到了调用!
注:ARC下的bridging,需要用到__bridge, __bridge_retained, __bridge_transfer修饰符,本文不作讨论。
Toll free briding 是用于 Foundation对象和Core Foundation对象间无缝转换的一种方法。首先,我们来看看下面代码:
-
-
- Read More -
- - -在Mac上简单的编译出一个可以在 IOS 上运行的 hello world 程序:
- -- Read More -
- - -对于 NSInputStream 和 NSOutputStream 一直没怎么搞清楚,今天抽一些时间在此记录一下!
-NSInputStream 与 NSOutputStream 都继承于 NSStream, NSStream 是一个抽象的基类, 规定了Stream共有的一些行为…
- -- Read More -
- - -最近接触到了Mantle这个东西,感觉很不错,在此与各位分享一下。
-
-
- Read More -
- - -不知道从什么时候开始IOS的SDK里多了一个叫instancetype的东西,顾名思义返回的就是一个实例对象,所以也没有深究。 但是这玩意和以前的id有什么区别呢,突然比较好奇。 上网查看了下相关的资料,自己也做了下测试,在这里记录一下。
-
-
- Read More -
- - -在我的配置过程中出现很多问题,比如说tag-cloud不能显示,中文不能支持,还有添加评论、日历的插件没有搞上去。这个真的太考验动手能力了……..
说实话,我更喜欢博客园写博客。 以后慢慢的熟练吧! 下面转载几篇比较好的配置教程:
-
-
- Read More -
- - -这是搭建好Octopress写的第一篇博客,搭建过程中遇到了不少麻烦,但最后还是成功搭建出来了,感觉还不错。 还有很多东
西需要琢磨,比如主题、markdown语法、博客写作….总之,需要花时间折腾一下才行。