最近一个项目需要保存到本地文件,想用plist,但是发现很多内容是自定义的,于是只能自己归档接档。不难,找了一篇范文大家保存一下,方便以后学习使用。

转自:http://mobile.51cto.com/iphone-282203_4.htm

iPhone开发应用之Archiving NSCoder教程是本文要介绍的内容,一个面向对象程序在运行的时候,一般都创建了一个复杂的对象关系图,经常需要把这样一个复杂的对象关系图表示成字节流.这样的过程我们叫做Archiving 如图10.1,

这个字节流可以在网络中传送,也可以写入到文件中. 例如,我们创建保存一个nib文件,Interface Builder把对象写入到nib文件就是这样的arching过程(对于Java,这个过程叫serialization)。

而当从字节流中重新恢复对象关系图的过程叫做unarchive. 例如,当程序启动是,将会从nib文件中unarchive对象虽然对象包含成员变量和方法.但是只有成员变量和类名会被archive. 换句话说,data会被archive,而code不会. 所以,如果程序A archive对象,而程序B unarchive对象.那么程序A和B都要保证包含了class所连接的code. 举个例子,在nib文件中,你使用到了Appkit framework 的NSWindow和NSButton对象.那么如果我们的程序没有连接Appkit framework,那么我们就没有办法生成NSWindow和NSButton对象,因为archive中只包含了data,而没有code

有一个洗发水的广告是这样说得:"我告诉了我的两个朋友,而他们各自又告诉了自己的两个朋友,这样一传十,十传百.."寓意就是,你告诉了你的朋友,最后所有的人都开始使用这个洗发水了. 对象archiving的工作方式和这差不多. 你archiving一个root对象. 它archiving自己相关联的对象,那些相关联的对象也会archiving自己相关联的对象,依次类推,所有相关的对象都被archiving了

archiving由2步来完成. 1,我们需要告知我们的对象要怎么样来archive. 2. 我们需要激发archiving动作发生

Objective-C语言有一个机制叫protocol, 就像java中的interface一样. 一个protocol声明了一系列方法.但你的类实现一个protocol,那么就预定了,你的类需要实现protocol中声明的所有方法

NSCoder NSCoding

NSCoding是一个protocol. 如果你的类实现了NSCoding.那么就要实现这些方法

- (id)initWithCoder:(NSCoder *)coder;   - (void)encodeWithCoder:(NSCoder *)coder;

NSCoder是archivie 字节流的抽象类.我们可以实现把数据写入一个coder,也可以从coder中读取我们写入的数据. 我们对象的方法initWithCoder:就是从一个coder从读取数据,然后把数据赋给成员变量. 方法encodeWithCoder: 则是把成员变量的值写入到coder中. 在这一章中,我们会在Person类中实现这两个方法

NSCoder是一个抽象类,我们不会直接使用它来创建对象. 相反,我们会使用从它继承来的子类. 也就是我们使用 NSKeyedUnarchiver类来从字节流中读取数据,而使用NSKeyedArchiver类来把对象写入到字节流

Encoding

NSCoder包含了很多方法, 不过大部分人会发现只会使用到其中很少的一部分. 下面是当要archivie数据时用到的一些常用方法

- (void)encodeObject:(id)anObject forKey:(NSString *)aKey

这个方法把anObject对象写入到coder中,并把它和aKey关联起来[下次使用aKey从coder中可以再把anObject读取出来] 这会是anObject的方法encodeWithCodr得到调用(还记得上面那个洗发水广告把.就是这样传下去的)

对于C的基本类型(如int float).NSCoder使用下面方法

 - (void)encodeBool:(BOOL)boolv forKey:(NSString *)key  
- (void)encodeDouble:(double)realv forKey:(NSString *)key  
- (void)encodeFloat:(float)realv forKey:(NSString *)key  
- (void)encodeInt:(int)intv forKey:(NSString *)key

添加encoing方法到Person类中.

 - (void)encodeWithCoder:(NSCoder *)coder  
{  
   [super encodeWithCoder:coder];  
    [coder encodeObject:personName forKey:@"personName"];  
    [coder encodeFloat:expectedRaise forKey:@"expectedRaise"];  

这里调用了父类的encodeWithCoder,使得父类有机会把自己的变量写入到coder中. 因此,类继承树中的类只会把自己的成员变量写入到coder-不会包含父类的成员变量

Decoding

从coder中decoding数据,我们使用这些方法

 - (id)decodeObjectForKey:(NSString *)aKey  
- (BOOL)decodeBoolForKey:(NSString *)key  
- (double)decodeDoubleForKey:(NSString *)key  
- (float)decodeFloatForKey:(NSString *)key  
- (int)decodeIntForKey:(NSString *)key

如果因为某些原因, 字节流中没有和aKey关联的数据,那么我们会得到0值. 例如,对象没有把key foo 关联一个float数据写入coder,那么在使用foo key来读取这个float数据,coder会返回0.0 . 如果key foo关联的是一个对象数据[使用方法encodeWithCoder 写入],那么读取时coder返回nil

添加decoding到Person类中

 - (id)initWithCoder:(NSCoder *)coder  
{  
   [super init];  
   personName = [[coder decodeObjectForKey:@"personName"] retain];  
   expectedRaise = [coder decodeFloatForKey:@"expectedRaise"];  
   return self;  

我们没有调用父类的initWithCoder, 那是因为NSObject没有实现它. 如过Person类的父类实现了NSCoding协议,那么这个方法应该这样写

 - (id)initWithCoder:(NSCoder *)coder  
{  
  [super initWithCoder:coder];  
  personName = [[coder decodeObjectForKey:@"personName"] retain];  
  expectedRaise = [coder decodeFloatForKey:@"expectedRaise"];  
  return self;  

你可以会说"在第3章中, designated initializer会完成所有的init工作然后在调用父类的 designated initializer, 也就是说类的其他initializer 方法都会调用designated initializer,Person类有designated initializer- init. 可以这个新加入的initializer方法并没有调用init方法阿?" 不错, 你是对的, initWithCoer: 是这个规则的一个特例.

好了.我们实现了NSCoding协议的方法.现在让Person类实现NSCoding protocol. 我们来编辑Person.h文件.

@interface Person : NSObject <</span>NSCoding> {

现在编译我们的工程. 你也可以运行程序看看.虽然Person类可以encode自己了.不过我们没有地方让它这么做.所以程序看上去没什么变化.

Document Architecture

多文档程序有很多的共同性. 比如都可以创建新的document, 打开document,保存或打印打开的document, 当关闭document窗口或退出程序时提醒用户保存编辑好得document. Apple提供3个类- NSDocumentController,NSDocument,NSWindowController-来完成这些工作. 它们一起组成了document architecture

创建document architecture的意图是和我们第8章讨论的Model-View-Controller设计模式相关的. 在RaiseMan工程中. 我们的NSDocument子类-使用了NSArrayController类-就是其中的Controller. 它包含了指向model对象的指针. 负责下面所列的职责 [这里的model 数据就是值employyess-person 对象]

将model 数据保存为一个文件

从一个文件中加载model数据

在view中显示model数据

响应用户通过view的输入,并更新model

Info.plist NSDocumentController

XCode在编译创建一个程序时会使用到一个文件 Info.plist(本章后面,我们会修改这个文件). 当程序启动时,它会读取Info.plisst的信息. 告知工作的文件类型是什么. 如果它发现是一个document-base 程序. 那么会创建一个NSDocumentController对象(图10.2). 我们很少去直接使用这个document controller. NSDocumentController对象在后面会为我们做一些工作.例如,当选择New 或是 Save All菜单时, document controller会处理这些请求. 如果你有给document controller发送消息,你可以这样做

NSDocumentController *dc;   dc = [NSDocumentController sharedDocumentController];

document controller保存了一个document 对象的array - 每一个document对象就是一个打开的document.

NSDocument

document对象是NSDocument子类的一个实例. 在我们的RaiseMan程序中,它就是MyDocument的实例. 对于大部分程序,一般我们只有简单的扩展NSDocument来完成想要的功能而不需要过多关系NSDocumentcontroller或是NSWindowController

saving

菜单项Save,Save As...,Save All,和Close虽然不相同.但是它们都面向同一个问题:把mdoel保存为一个文件或是文件包(文件包是一个文件目录,不过对于用户就象是一个文件一样). 对于这些菜单项. 我们的NSDocument子类需要实现下面3个方法中的一个

- (NSData *)dataOfType:(NSString *)aType                  error:(NSError *)e

你的document对象将model生成一个NSData写入文件.[这个方法中,我们只有把model压成一个NSData返回,然后Cocoa会把NSData在写入文件了] NSData就是字节buffer. 是简单也是通用的实现saving的方法.如果不能生成一个NSData 对象,那么就返回nil,而用户会得到一个alert提示save失败. 注意到参数aType, 它可以容许你将document保存为一个或多个类型格式. 例如,你编写了一个图像程序,你可能容许用户将图像保存为gif或是jpg格式.所以当你生成data对象时, aType就指定了用户请求保存的格式.如果你的程序只处理单一类型,那么可以忽略aType. 为了说明你不能保存,可以返回nil并创建一个NSError对象来说明出来什么样得错误

- (NSFileWrapper *)fileWrapperOfType:(NSString *)aType                             error:(NSError *)e

你的document对象生成一个文件包返回. 文件包将被创建在用户指定的位置

 - (BOOL)writeToURL:(NSURL *)absoluteURL  
            ofType:(NSString *)typeName  
             error:(NSError **)outError;

你的docuemnt对象以指定的type把model数据保存在指定的URL(URL就是文件系统上的文件路径)[这个方法应该在NSDocument类中实现了,里面估计就是调用了dataOfType:error: . 得到NSData后将其写入指定URL. 当然你也可以从中这个方法] 如果能够保存成功返回YES,否则返回NO. 如果返回NO,那么你你应该生成一个NSError对象来描述错误是什么

来解释下NSError.它的观念是,因为某些原因,某个方法没有办法完成这个功能.那么它就会生成一个NSError对象,并把NSError对象的指针放到指定的位置. 例如,如果我希望从一个文件中读取到一个NSData,那么我会提供一个地址,当出错时,我可以从这个地址中得到错误信息
NSError *e;

 NSData *d = [NSData dataWithContentsOfFile:@"/tmp/x.txt"  
                                   options:  
                                     error:&error];  
// Did the read fail?  
if (d == nil) {  
    NSLog(@"Read failed: %@", [error localizedDescription];
}

所以NSData类即会返回一个data对象,同时可能会创建一个error对象

在save和load方法中,我们将有负责在失败的时候创建NSError对象

Loading

Open...,Open Recent,和Revert To Saved 菜单项也是一样,它们都面向同一个问题:从一个文件或是文件包中得到model. 为了响应它们,NSDocuement子类需要实现下面3个方法中的一个

 - (BOOL)readFromData:(NSData *)data  
              ofType:(NSString *)typeName  
               error:(NSError **)outError 

包含了用户要打开的文件内容的NSData对象被传进来. 如果能够从这个NSData对象中生成model那么就返回YES. 如果返回NO,那么用户会得到一个Alert提示为什么个不能成功打开文件. Alert的内容由这个方法生成的NSError对象来指定

 - (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper  
                     ofType:(NSString *)typeName  
                      error:(NSError **)outError;

从一个NSFileWrapper对象读取model数据

 - (BOOL)readFromURL:(NSURL *)absoluteURL  
             ofType:(NSString *)typeName  
              error:(NSError **)outError; 

从指定文件中读取model数据

在实现了一个save和一个load方法后,我们的程序就知道怎么样读写文件了.在打开一个文件时, document对象会在读取nib文件前读取document文件[你需要读取nib文件来显示一个document阿] . 这样的结果是,我们不能在loading一个document文件后马上去给用户界面发送消息(它们还不存在)[注意load nib文件是document 架构为我们做的,这里说的立马调用是指在 load方法中-这个是我们在NSDocument子类中实现的调用-给UI发送消息]. [那如果我们想要马上给UI发送消息怎么办?]-为了解决这个问题,我们可以实现一个方法-它会在nib文件被调用UI创建好了后发送

- (void)windowControllerDidLoadNib:(NSWindowController *)x;

[想想 当点击Open菜单,代码执行的过程是怎么样 - 有些代码是cocoa里面实现的,有些是我们自己实现的]

在我们的NSDocuemnt 子类中,实现这个方法刷新UI

NSWindowController

在document architecture中最后要介绍的一个类是NSWindowcontroller .每打开一个Document都会产生一个窗口-生成一个NSWindowController实例. 对于大部分程序,每一个document对于一个window, window controller的默认实现已经够用了.所以一般我们只有在下面几种情况下才会生成一个NSWindowController的子类

对于同一个document,需要使用多个window. 例如,CAD程序, 你可能需要一个text窗口来描述一个立体,而另外一个窗口来显示这个立体

你需要把UI controller 和 model controller 放到不同的类中

你需要创建不和NSDocument 对象对应的窗口.我们会在12章来做这样的事

Saving NSKeyedArchiver

现在我们知道了怎样encode和decode我们自己的类,现在开始给我们的程序添加saving和loading功能了. 当我们要保存person到一个文件,MyDocument类会被请求生成一个NSData实例. 一旦创建了NSData实例并返回,它会自动保存到文件中

为了生成一个NSData实例[encode了model数据] , 我们使用NSKeyedArchiver类. 它有这样一个方法

+ (NSData *)archivedDataWithRootObject:(id)rootObject

这个方法将对象archive成NSData对象的字节buffer [字节buffe-看看NSData的说明吧]

再一次回到那个广告"我告诉了两朋友,他们也告诉了自己的朋友...."当你encode一个对象是, 这个对象会encode它自己连接的对象,那些对象也会encode它们连接的对象..等等. 这里我们要encode那个对象呢?就是array employees了. 它又会encode所有包含的Person对象. 而我们在Peron类中实现了encodeWithCoder:,所以每个Perosn对象开始encode自己了-encode personName字串和expectedRaise float

编辑方法dataOfType:error:. 添加saving功能

 - (NSData *)dataOfType:(NSString *)aType  
                 error:(NSError **)outError  
{  
    // End editing  
    [[tableView window] endEditingFor:nil];  
 
    // Create an NSData object from the employees array  
    return [NSKeyedArchiver archivedDataWithRootObject:employees];  
}

这里我们忽略了error参数.将没有error产生

Loading和NSKeyedUnarchiver

  

现在开始添加load文件功能, 再一次说明,NSDocument已经大部分细节

我们会使用到NSKeyedUnarchiver类方法

+ (id)unarchiveObjectWithData:(NSData *)data

编辑MyDocument类的readFromData:ofType:error:方法

 ofType:(NSString *)typeName  
               error:(NSError **)outError  
{  
   NSLog(@"About to read data of type %@", typeName);  
   NSMutableArray *newArray = nil;  
   @try {  
      newArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];  
   }  
   @catch (NSException *e) {  
      if (outError) {  
         NSDictionary *d = [NSDictionary  
              dictionaryWithObject:@"The data is corrupted."  
                            forKey:NSLocalizedFailureReasonErrorKey];  
         *outError = [NSError errorWithDomain:NSOSStatusErrorDomain  
                                         code:unimpErr  
                                     userInfo:d];  
     }  
      return NO;  
}  
   [self setEmployees:newArray];  
   return YES;  

在nib文件加载后,你需要刷新UI.不过NSArrayController为你完成了这个功能.我们不需要在windowControllerDidLoadNib:方法中多做什么. 我们在13章将会修改这个方法

 - (void)windowControllerDidLoadNib:(NSWindowController *)aController  
{  
    [super windowControllerDidLoadNib:aController];  

注意,在打开或创建一个document时,会询问我们的document类:需要load那个nib文件.现在我们也不需要修改这个方法

 - (NSString *)windowNibName  
{  
    return @"MyDocument";  

因为我们激活了undo 机制,所以在编辑了document后, window会自动标注为编辑过.

现在,我们的程序能够读写文件了.编译运行程序,试试看吧,看上去都能工作正常. 不过我们保存的文件的后缀名为.???? ,我们需要在Info.plist中给它定义一个后缀名

设置后缀名和图标

我们将为RaiseMan 文件添加后缀.rsmn 和一个图标. 首先找到一个.icns文件并拷贝到我们的工程中. 就使用

/Developer/Examples/Appkit/CompositeLab/BBall.icns

  

吧.把他从Finder中拖到XCode的Resources组中.如图10.3

XCode会弹出一个页面,确保勾选Copy items into destination group's folder 如图10.4.这样将会包icon文件拷贝到我们的工程目录中

在XCode中选定RaiseMan Target, 从File菜单中选择Get Info, 来设置document-type属性. 在Properties页中,设置identifier为com.bignerdranch.RaiseMan. 设置Icon file 为BBall. 在document-types中,设置name为RaiseMan Doc. Extensions为rsmn. icon file为BBall.参考图10.5

编译运行程序.我们再次试试保存和打开功能. 在Finder中, 我们的.rsmn文件的图标变成了BBall.icns

一个程序其实是一个目录. 包含了程序用到的nib 文件, 图像,声音和可执行代码. 在Terminal,试试输入

cd /Applications/TextEdit.app/Contents   ls

可以看到3个有趣的东西

Info.plist文件. 包含了该程序的信息, 文件类型和相关的图标. Finder会使用这些信息

MacOS/目录. 这里包含了可执行代码

Resources/目录. 这里包含了程序用到的图像,声音和nib文件,你还可以看到不同语言的本地化资源

思考:避免死循环

聪明的读者可能会怀疑:""如果对象A使对象B进行encode,对象B使对象C进行encode,而对象C又使得对象A进行encode. 这样不是会产生无穷循环吗?"" 没错,确实会发生这种情况,好在NSKeyedArchiver类设计好了避免这种情况发送.

当encode一个对象的时候,会将一个唯一标识同时放到流中.并建立一个表,一旦archive对象,就会把该对象和它的唯一标识联系起来. 如果下次又要encode同一个对象,NSKeyedArchiver会先浏览这个表,看是否已经encode过,并只会把唯一标识放置到流中.

当从流中decode出对象时, NSKeyedUnarchiver同样会生成一个表,把encode对象和唯一标识关联起来.如果发现流中只有唯一标识[说明之前有encode这个对象],unarchiver就会在表中来查找这个对象,而不是再生成一个新的对象.

NSCoder有一个方法容易使读者和上面的思想产生混淆

- (void)encodeConditionalObject:(id)anObject forKey:(NSString *)aKey

当对象A有一个指针指向对象B, 但是对象A不需要知道对象B是否被archive[是否存在]. 不过如果另外一个对象已经archive了B,对象A又希望将对象B的唯一标识在encode的时候能够放置到流中.  [也就是说对象A不会主动encode B, 如果存在对象B ,那么就指向它,否则就指向空]

举个例子,我们需要给Engine对象编写它的encodeWithCoder:方法. 它有一个成员变量为car,是一个指向Car对象的指针(发动机是汽车的一部分). 我们在archiving Engine对象时,不希望整个Car对象被archived. 不过如果该Car对象之前在其他地方archived过, 我们又希望 Engine对象的car指针指向它. 在这种情况下,我们就要要求Engine对象有条件的来encode car指针指向的对象了. 如图10.6

思考: 创建Protocol

创建自己的Protocol非常简单.下面的Protocol有两个方法,它可能在Foo.h文件中

 @protocol Foo  
- (void)fido:(int)x;  
- (float)rex;  
@end

Objective-C 2.0中,新增了语法@optional. 可以用来指定那些方法是必须那些方法是可选的

 @protocol Foo  
- (void)fido:(int)x;  
- (float)rex;  
@optional  
- (int)rover;  
- (void)spot:(int)x;  
@end

在这个例子中fido: 和rex方法是必须的,而rover和spot:方法是可选的

如果你有一个类要实现Foo protocol和NSCoding protocol. 应该这样做

 #import "Spunky.h"  
#import "Foo.h"  
 
@interface ZsaZsa:Spunky <</span>Foo, NSCoding> 
...etc...  
@end

我们不需要重新声明父类和protocol中声明过的方法.所以,在本例中, ZsaZsa类接口文件中不需要再次声明Spunky和Foo,NSCoding中声明过的方法

通用类型描述[UTI]

在使用计算机时,一直有这样一个问题:"数据是怎么样展现出来的". 对于Mac, 这个问题在不同的几个地方都会遇到:当从Finder打开一个文件时.当通过剪贴板拷贝数据时,当通过Spotlight索引文件时,当使用Quicklook预览文件时.这个问题有一些答案: 文件扩展名, creator codes,和MIME类型

Apple选择的长期解决途径是通用类型描述(UTIs). 一个UTI是一个描述了文件类型的字符串. UTIs按一定层次关系组织.

我们在Info.plist文件中定义程序可以读写的UTIs-包括新建的和自定义的UTIs. Info.plist文件是XML格式,包含了目录以及key-value.  可以使用一个新key UTExporterTypeDeclarations来export新的UTIs. 例如,如果你想给RaiseMain Document添加一个UTI. 可以在Info.plist文件中添加如下描述:

 <</span>array> 
    <</span>dict> 
        <</span>key>UTTypeIdentifier</</span>key> 
        <</span>string>com.bignerdranch.raiseman-doc</</span>string> 
        <</span>key>UTTypeDescription</</span>key> 
        <</span>string>RaiseMan Document</</span>string> 
        <</span>key>UTTypeConformsTo</</span>key> 
        <</span>array> 
              <</span>string>public.data</</span>string> 
        </</span>array> 
        <</span>key>UTTypeTagSpecification</</span>key> 
 
        <</span>dict> 
              <</span>key>com.apple.ostype</</span>key> 
              <</span>string>rsmn</</span>string> 
              <</span>key>public.filename-extension</</span>key> 
              <</span>array> 
                   <</span>string>rsmn</</span>string> 
              </</span>array> 
        </</span>dict> 
    </</span>dict> 
</</span>array>

当然,我们也通过properties inspector来使用UTI.如图10.7

你可以在Apple的文档中找到所有的系统定义的UTIs

[转载]iOS 归档操作 NSCoding的更多相关文章

  1. iOS阶段学习第18天笔记(Plist-Archiver-归档与解归档操作)

    iOS学习(OC语言)知识点整理 一.归档与解归档的操作 1)归档是一个过程,将一个或多个对象存储起来,以便以后可以还原,包括将对象存入文件,以后再读取 将数据对象归档成plist文件 2)plist ...

  2. iOS数据库操作之coredata详细操作步骤

    CHENYILONG Blog iOS数据库操作之coredata详细操作步骤 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/ ...

  3. iOS 数据库操作(使用FMDB)

    iOS 数据库操作(使用FMDB)   iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.Plausibl ...

  4. iOS——文件操作NSFileManager (创建、删除,复制,粘贴)

    iOS——文件操作NSFileManager (创建.删除,复制,粘贴)       iOS的沙盒机制,应用只能访问自己应用目录下的文件.iOS不像android,没有SD卡概念,不能直接访问图像.视 ...

  5. IOS文件操作的两种方式:NSFileManager操作和流操作

    1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...

  6. IOS数据库操作SQLite3使用详解(转)

    iPhone中支持通过sqlite3来访问iPhone本地的数据库.具体使用方法如下1:添加开发包libsqlite3.0.dylib首先是设置项目文件,在项目中添加iPhone版的sqlite3的数 ...

  7. 基于facebook-wda的iOS自动化操作实践记录

    [本文出自天外归云的博客园] 原理 对于iOS自动化操作,主要靠WebDriverAgent来完成.在Mac电脑上连接真机iPhone,运行WebDriverAgentRunner会在Mac端启动WD ...

  8. iOS 线程操作库 PromiseKit

    iOS 线程操作库 PromiseKit 官网:http://promisekit.org/ github:https://github.com/mxcl/PromiseKit/tree/master ...

  9. ios 沙盒 NSCoding(相当于JAVA对象序列化) 归档 数据存储

    通过NSCoding能实现像JAVA一样能够实现对象的序列化,可以保存对象到文件里. NSCoding 跟其他存储方式略有不同,他可以存储对象 对象存储的条件是: 对象需要遵守 NSCoding 协议 ...

随机推荐

  1. cocos2d-x 中的基本概念

    在 cocos2d-x 开头配置(Windows 平台)中,介绍了新建工程,这篇就介绍下 cocos2d-x 的一些概念.(前提是需要有C++的面向对象的基本知识和C++11的常用知识) 层,场景,导 ...

  2. eval解析非标准json

    以前一直在用,但是不知道原理,惭愧啊,今天把自己想法加上. eval("{a:1}"); eval("{a:,b:1}"); 第一眼的感觉是都会得到一个对象,其 ...

  3. SSH(2)

    1.用户登录 index页面跳转到登录页面 <% String path = request.getContextPath(); String basePath = request.getSch ...

  4. Struts1的核心对象

    1.ActionServlet.ActionMapping.ActionForm.ActionForward 2.config = "/WEB-INF/struts-config.xml&q ...

  5. fifo read

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...

  6. phonegap 框架详解

    首先, 来看一下phonegap 初始化流程以及Native 与 JS 交互流程图. 说明:socket server模式下, phonegap.js 源码实现的采用1 毫秒执行一次XHR请求,  当 ...

  7. checkbox 全选,反选 ,全不选

    在表格或者列表中经常会遇到要全选或者反选等交互,今天总结了一下代码,保留着以后直接拿来用 原理: 1. 全选:当全选checkbox被点击(不管点击之前是什么状态)后,获取其checked状态.然后对 ...

  8. HttpContext.Current.Cache 和HttpRuntime.Cache的区别

    先看MSDN上的解释:      HttpContext.Current.Cache:为当前 HTTP 请求获取Cache对象.      HttpRuntime.Cache:获取当前应用程序的Cac ...

  9. 线程和NSThread 、 NSOperation

    1 使用NSThread实现打地鼠 1.1 问题 NSThread是ios提供的轻量级的多线程解决方案,但是需要自己管理线程的生命周期.线程同步等.本案例使用NSThread实现一个打地鼠的小游戏,在 ...

  10. 从数学角度看最大期望(EM)算法 II

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2015/3/13 对于隐变量只有有限个取值(比如$N$个)的情况,我们可以将隐变量表示为${z_j} = [{z_{j ...