??xml version="1.0" encoding="utf-8" standalone="yes"?>
//?/span>Foundation(NSDictionary?/span>NSData) 转换?/span>JSon格式?/span>NSData 用来发?/span>
//+ dataWithJSONObject:options:error:
//?/span>JSON格式?/span>Data转换?/span>Foundation(NSDictionary?/span>NSData) 用来解析
//+ JSONObjectWithData:options:error:
code:
目录
一、基本概?/p>
1、什么是版本控制
2、什么是 Subversion
3、版本库(repository)
二、安?/p>
1、准备工?/p>
2、安?a title="服务? target="_blank" style="text-decoration: none; color: #000000; cursor: pointer; ">服务?/a>端和客户?/p>
3、徏立版本库(Repository)
4、运行独立服务器
三、基本配|?/p>
1、配|用户和权限
2、初始化导入
四、基本操作流E?/p>
1、取?check out)
2、存?check in)/提交(commit)
------------------------------------------------------------------??U?--------------------------------------------------------------
一、基本概?/strong>
1、什么是版本控制
单点来说Q版本控制就是数据仓库,它可以记录你Ҏ(gu)件的每次更改。这Pq你在昏天黑地的改了几个月后老板说不要了Q还是按照过去那P你也不会抓狂Q简单的恢复版本操作搞定一切?/p>
2、什么是 Subversion
Subversion是一个自?开源版本控制系l,它管理文件和目录可以越旉。一l文件存攑֜中心版本库,q个版本库很像一个普通的文g服务器,只是它可以记录每一ơ文件和目录的修改,q便使你可以取得数据以前的版本,从而可以检查所作的更改。从q个斚w看,许多人把版本控制pȝ当作一U?#8220;旉机器”?/p>
Subversion可以通过|络讉K它的版本库,从而用户可以在不同的?sh)脑上用。一定程度上可以_允许用户在各自的地方修改同一份数据是促进协作。进展可能非常的q速,q没有一个所有的改变都会取得效果的通道Q由于所有的工作都有历史版本Q你不必担心׃失去某个通道而媄响质量,如果存在不正的改变Q只要取消改变?/p>
一些版本控制系l也?a title="软g" target="_blank" style="text-decoration: none; color: #000000; cursor: pointer; ">软g
配置理(SCM)pȝQ这U系l经q特定的_y设计来管理源代码Q有许多关于软g开发的Ҏ(gu)?#8212;本n理解~程语言、或者提供构建程序的工具。然而,Subversion不是q样一个系l,它是一个通用pȝQ可以管理Q何类型的文g集,对你q可能是源代码,对别人,可能是一个货物报价单或者是书稿Q或者是?sh)媄剪辑{?/p>3、版本库(repository)
Subversion 的核心就?repository Q中文翻译成“版本?#8221;。就是位于服务器端,l一理和储存数据的地方?/p>
二、安?/strong>
Subversion的设计包括一个抽象的|络层,q意味着版本库可以通过各种服务?/a>q程讉K。理ZԌSubversion可以使用无限数量的网l协议实玎ͼ目前实践中存在着两种服务?/a>?/p> • SVNServerQsvnserve 是一个小?也叫d?、独立服务器Q用自己定义的协议和客L?作者注Q以下称q种服务器ؓ“svnserver服务?#8221;? • ApacheSVNQApache是最行的web服务器,通过使用 mod_dav_svn 模块QApache可以讉K版本库,q且可以使客L使用HTTP的扩展协议WebDAV/DeltaVq行讉K?作者注Q以下称q种服务器ؓ“ApacheSVN服务?#8221;? 下面介绍 SVNServer 服务器的安装QApacheSVN 服务器的安装使用L我写的《Subversion高应用QSVN的多U认证方式》?/p> 环境 OSQWindows XP SP2 WebQApache 2.2.6 SVNQsvn-win32-1.4.6 1、准备工作?/p> (1)获取 Subversion 服务器程序?/p> 到官方网?http://subversion.tigris.org/)下蝲最新的服务器安装程序。目前最新的?.4.6版本Q具体下载地址在:http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100&expandFolder=8100&folderID=91 Q注意找 for apache 2.2.x 版本的?/p> (2)获取 TortoiseSVN 客户端程序?/p> 从官方网?http://tortoisesvn.net/downloads 获取最新的 TortoiseSVN 。TortoiseSVN 是一个客LE序Q用来与 subvers 服务器端通讯。Subversion 自带一个客LE序 svn.exe ,?TortoiseSVN 更好操作Q提高效率?/p> 2、安装服务器端和客户?/p> 首先安装 Apache 2.2.6 Q具体安装方法大家参考相兌料,或者参看我写的《Windows下安装Apache 2.2.x》?/p> 其次安装 Subversion(以下USVN)的服务器端和客户端。下载下来的服务器端是个 zip 压羃包,直接解压~即可,比如我解压到 E:\subversion 。客L安装文g是个 exe 可执行文Ӟ直接q行按提C安装即可,客户端安装完成后提示重启?/p> 3、徏立版本库(Repository) q行Subversion服务器需要首先要建立一个版本库(Repository)。版本库可以看作是服务器上集中存攑֒理数据的地斏V?/p> 开始徏立版本库。首先徏?e:\svn I文件夹作ؓ所有版本库的根目录。然后,q入命o行ƈ切换到subversion的bin目录。输入如下命令: 此命令在 E:\svn 下徏立一个版本库 repos1 。repos1 下面会自动生成一些文件夹和文件?/p> 我们也可以?TortoiseSVN 囑Ş化的完成q一步: 先徏立空目录 E:\svn\repos1 Q注意一定是要空的。然后在 repos1 文g夹上“右键->TortoiseSVN->Create Repository here...”Q然后可以选择版本库模式,q里使用默认的FSFS卛_Q然后就创徏了一pd文g夹和文gQ同命o行徏立的一栗?/p> 4、运行独立服务器 此时 subversion 服务q没有开始,只是通过它的命o建立了版本库。l在刚才的命令窗口输入: svnserve 会在端?3690 {待hQ?-daemon(两个短横U?选项告诉 svnserve 以守护进E方式运行,q样在手动终止之前不会退出。注意不要关闭命令行H口Q关闭窗口会?svnserve 停止?/p> Z验证svnserve正常工作Q用TortoiseSVN -> Repo-browser 来查看版本库。在弹出?URL 对话框中输入Q?nbsp; ?OK 按钮后就可以看见 repos1 版本库的目录树结构了Q只不过q时 repos1 是个I库?/p> 你也可以使用--root选项讄根位|来限制服务器的讉K目录Q从而增?a title="安全" target="_blank" style="text-decoration: none; color: #000000; cursor: pointer; ">安全
以前面的试作ؓ例,svnserve 会q行为:
然后TortoiseSVN中的版本库浏览器URL~减为:
三、基本配|?/strong>
SVNServer服务?/a>安装完成后,必须l过基本配置才能使用?/p> 1、配|用户和权限 用文本编辑器打开E:\svn\repos1\conf目录Q修改svnserve.confQ?/p> : 改ؓQ?nbsp; 卛_掉前面的 # 注释W,注意前面不能有空根{?/p> 然后修改同目录的passwd文gQ增加一个帐P : 增加帐号Q?/p> 2、初始化导入 下面是我们的数据(目)导入到这个版本库Q以后就q本库理我们的数据。我们的M改动都会被版本库记录下来Q甚x们自׃失、改错数据时版本库也能帮我们扑֛数据?/p> 比如Q我?d:\wwwroot 下有?guestbook 文g夹,里面存放的是我编写的留言程序。在此文件夹?#8220;右键 -> TortoiseSVN -> Import...” Q在弹出对话框的“URL of repository”输入“svn://localhost/repos1/guestbook”。在“Import message”输入“导入整个留言?#8221;作ؓ注释?/p> ?OK 后要求输入帐受我们在用户名和密码处都输入 test 。完成后 guestbook 中的内容全部导入C svn://localhost/svn/repos1/guestbook ?/p> 我们看到?e:\svn\repos1 没有M变化Q连?guestbook 文g多w没有建立Q唯一的变化就是e:\svn\repos1定w变大了。实际上我们源guestbook中的内容已经导入 repos1 版本库了Q源 guestbook 文g夹可以删除了?/p> 需要注意的是,q一步操作可以完全在另一台安装了 TortoiseSVN 的客h上进行。例如运行svnserve的主机的IP?33.96.121.22Q则URL部分输入的内容就?#8220;svn://133.96.121.22” ?/p> 四、基本操作流E?/strong> 1、取?check out) 取出版本库到一个工作拷贝: 来到LI目录下Q比如在f分区建立一个空文g?f:\work ?#8220;右键 -> SVN Checkout”。在“URL of repository”中输?#8220;svn://localhost/svn/repos1/guestbook”Q这h们就得到了一?guestbook 中内容的工作拯?/p> 2、存?check in)/提交(commit) 在工作拷贝中作出修改q提交: ?guestbook 工作拯中随便打开一个文Ӟ作出修改Q然?#8220;右键 -> SVN Commit... ”。这h们就把修Ҏ(gu)交到了版本库Q版本库Ҏ(gu)情况存储我们提交的数据?/p> 在修改过的文件上“右键 -> TortoiseSVN -> Show Log” Q可以看到对q个文g所有的提交。在不同?revision 条目?#8220;右键 -> Compare with working copy”Q我们可以比较工作拷贝的文g和所?revision 版本的区别?/p>
# harry = harryssecret
# sally = sallyssecret
#harry = harryssecret
#sally = sallyssecret
test = test
UI׃说了Q比较简单。脓(chung)一下关键代码,具体的话q是ȝ源代?正想办法传,我这git出点问题)?/p>
/*Ҏ(gu)路径创徏数据库ƈ创徏一个表contact(id nametext addresstext phonetext)*/
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:databasePath] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS(ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT,PHONE TEXT)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg)!=SQLITE_OK)
{
status.text = @"创徏表失?/span>\n";
}
}
else
{
status.text = @"创徏/打开数据库失?/span>";
}
}
}
/*数据保存只数据库,当按下保存按钮的时?/
- (IBAction)SaveToDataBase:(id)sender
{
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK) {
NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO CONTACTS (name,address,phone) VALUES(\"%@\",\"%@\",\"%@\")",name.text,address.text,phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement)==SQLITE_DONE) {
status.text = @"已存储到数据?/span>";
name.text = @"";
address.text = @"";
phone.text = @"";
}
else
{
status.text = @"保存p|";
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
/*Ҏ(gu)输入的姓名来查询数据*/
- (IBAction)SearchFromDataBase:(id)sender
{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:@"SELECT address,phone from contacts where name=\"%@\"",name.text];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *addressField = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
address.text = addressField;
NSString *phoneField = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 1 )];
phone.text = phoneField;
status.text = @"已查到结?/span>";
[addressField release];
[phoneField release];
}
else {
status.text = @"未查到结?/span>";
address.text = @"";
phone.text = @"";
}
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
}
}
举个例子Q加入对象A无法处理消息funQ而对象B可以处理Q此时A已经l承于类CQ所以此时A不能再承B。我们可以用消息转发的方式,来将消息转发l能够处理fun消息的对象B?/span>
当然可以q么实现
|
q样单的消息{发出去,但是此方式欠妥,特别是当很多消息都要A来处理,但是A又无法处理的时候,你需要实现各Ufun来提供每一U方法处理方式。ƈ且当写下代码的时候,所能处理的消息集合也就必须定下来Q也是说是静态的?/span>
有一U解x案可以解x问题 : forwardInvocationQ方法,此方法承与NSObject。不qNSObject中此Ҏ(gu)的实玎ͼ只是单的调用?span style="color: #666666; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; display: inline !important; float: none;">doesNotRecognizeSelector:
我们要做的是重写需要{发消息的cA?span style="color: #666666; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; display: inline !important; font-family: 'Hiragino Sans GB'; font-size: 13px;">forwardInvocationҎ(gu)Q以实现消息{发给能处理fun消息的对象?/span>
- (void)forwardInvocation:(NSInvocation *)anInvocation |
{ |
if ([B respondsToSelector:[anInvocation selector]) |
[anInvocation B]; |
else |
[super forwardInvocation:anInvocation]; |
} |
q有关键一步,是重?span style="color: #000000; font-family: Arial; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 26px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; display: inline !important; float: none;">methodSignatureForSelectorҎ(gu)Q此Ҏ(gu)是在向对象发送不能处理的消息的时候调用的Q此Ҏ(gu)可判断消息fun是否有效注册。如果注册过funQ那么则q回fun消息的地址之类的信息,如果无效则返回nilQ那么就crash掉。所以我们要把fun消息注册Z个有效的?/span>
|
q样一来,消息fun被转发至B?/p>
我们来说一下向一个对象发送消息后Q系l的处理程
1.首先发送消息[A fun];
2.pȝ会检查A能否响应q个fun消息Q如果能响应则A响应
3.如果不能响应Q则调用methodSignatureForSelector:来询问这个消息是否有效,包括ȝcM询问?/p>
4.接着调用forwardInvocation:此时步骤三返回nil或者可以处理消息的消息地址。如果nil则crashQ如果有可以处理fun消息的地址Q那么{发成功?/p>
大家都知道,如果一l数l作为参?/span>的话Q可以按如下Ҏ(gu)来定义函敎ͼ
int func(int *array);
或?/p>
int func(int array[M]); 其中M是数l的大小?/p>
二、二l数l作入参敎ͼ
而如?span style="line-height: normal;">输入参数是二l数l?/span>的话Q可以按如下Ҏ(gu)定义Q?/p>
1. 直接以二l数l作为参敎ͼ
int func(int array[M][N]);
或?int func(int array[][N]);
也就是说Q二l数l作为参敎ͼ可以省略W一l的大小Q但不可以省略第二维的大,因ؓ~译器在d时是按p + i * N + j来对p[i][j]q行d的,所以第二维参数必须l出?/p>
2. 以二l指针作为参敎ͼ
int func(int **array);
我们可以定义二维指针Q然后寻址时手工进行即可:*((int *)array + i * N + j)Q前面的(int *)是强制{换成指针cd?/p>
1.l定一个字W串Q输出本字符串中只出Cơƈ且最靠前的那个字W的位置Q?/strong>
比如"abaccddeeef" 则是bQ输?/span>2
int find_char(const char *str)
{
int pos[256];
const char *p = str;
if((!str)||!(*str))//I指针或者空?/span>
{
return -1;
}
memset(pos,-1,sizeof(pos));
//遍历一遍,存下每个字母的位|,如果存过一ơ,把位置讄?2
while (*p)
{
if (pos[*p] == -1)
{
pos[*p] = p - str;
}
else
{
pos[*p] = -2;
}
p++;
}
//遍历存储字母位置的数l,如果存有位置Q则q回
p = str;
while (*p)
{
if (pos[*p]>=0)
{
return pos[*p];
}
p++;
}
return -1;
}
2Q给定一个整敎ͼ问这个整数{?span style="font-family: Times; font-size: 12px; font-style: normal; font-variant: normal; line-height: normal; ">2q制后,里面包含有多个1Q比如:10Q二q制表示为,1010则,输出2
int howmany(int x)
{
int count = 0;
while (x)
{
if ((x&1) == 1)
{
count++;
}
x = x>>1;
}
return count;
}