KVC 字典对象和数组对象的键值编码

字典对象的键值编码

NSDictionary 定义了两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
如果字符串不是以 @ 开头的,将会调用 objectForKey: ; 如果有 @ 开头的就会以剩余的字符串
作为键,调用超类方法 alueForKey:

*/

- (id) valueForKey:(NSString *)key

/**
一般会调用 setObject:forKey: , value 为 nil 时,就会调用 removeObjectForKey: 删除
键对应的对象

*/

- (void) setValue: (id)value
forKey:(NSString *)key

数组对象的键值编码

NSArrayNSMutableArray 以及 集合类 NSSetNSMutableSet 也定义了两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
以 key 为参数,对于各个元素调用 valueForKey: 后返回数组,对各成员使用方法 valueForKey:,
当返回 nil 时,包含 NSNull 的实例。

*/

- (id) valueForKey:(NSString *)key

/**
对所有的元素调用 setValue:forKey: . 需要注意的是集合对象本身不可以改变,也可以调用这个
方法

*/

- (void) setValue: (id)value
forKey:(NSString *)key

Mysql 数据类型的属性

AUTO_INCREMENT

auto_increment能为新插入的行赋一个唯一的整数标识符。为列赋此属性将为每个新插入的行赋值为上一次插入的ID+1。
MySQL要求将auto_increment属性用于作为主键的列。此外,每个表只允许有一个auto_increment列。例如:

1
id smallint not null auto_increment primary key

BINARY

binary属性只用于char和varchar值。当为列指定了该属性时,将以区分大小写的方式排序。与之相反,忽略binary
属性时,将使用不区分大小写的方式排序。例如:

1
hostname char(25) binary not null

DEFAULT

default属性确保在没有任何值可用的情况下,赋予某个常量值,这个值必须是常量,因为MySQL不允许插入函数或表达式值。
此外,此属性无法用于BLOB或TEXT列。如果已经为此列指定了NULL属性,没有指定默认值时默认值将为NULL,否则默认值将
依赖于字段的数据类型。例如:

1
subscribed enum('0', '1') not null default '0'

INDEX

如果所有其他因素都相同,要加速数据库查询,使用索引通常是最重要的一个步骤。索引一个列会为该列创建一个有序的键数
组,每个键指向其相应的表行。以后针对输入条件可以搜索这个有序的键数组,与搜索整个未索引的表相比,这将在性能方面
得到极大的提升。

1
2
3
4
5
6
7
8
9
10
create table employees
(
id varchar(9) not null,
firstname varchar(15) not null,
lastname varchar(25) not null,
email varchar(45) not null,
phone varchar(10) not null,
index lastname(lastname),
primary key(id)
);

NOT NULL

如果将一个列定义为not null,将不允许向该列插入null值。建议在重要情况下始终使用not null属性,因为它提供了
一个基本验证,确保已经向查询传递了所有必要的值。


NULL

为列指定null属性时,该列可以保持为空,而不论行中其它列是否已经被填充。记住,null精确的说法是“无”,而不是空字符串或0。


PRIMARY KEY

primary key属性用于确保指定行的唯一性。指定为主键的列中,值不能重复,也不能为空。为指定为主键的列赋予auto_increment属性
是很常见的,因为此列不必与行数据有任何关系,而只是作为一个唯一标识符。主键又分为以下两种:

(1)单字段主键
如果输入到数据库中的每行都已经有不可修改的唯一标识符,一般会使用单字段主键。注意,此主键一旦设置就不能再修改。
(2)多字段主键
如果记录中任何一个字段都不可能保证唯一性,就可以使用多字段主键。这时,多个字段联合起来确保唯一性。如果出现这种情况,指定一
个auto_increment整数作为主键是更好的办法。


UNIQUE

被赋予unique属性的列将确保所有值都有不同的值,只是null值可以重复。一般会指定一个列为unique,以确保该列的所有值都不同。例如:

1
email varchar(45) unique

ZEROFILL

zerofill属性可用于任何数值类型,用0填充所有剩余字段空间。例如,无符号int的默认宽度是10;因此,当“零填充”的int值为4时,将
表示它为0000000004。例如:

1
orderid int unsigned zerofill not null

引用参考

Mysql 数据类型

数据类型

1.INT

  • SMALLINT

    1
    2
    3
    字节:2
    描述:整数,从-32000到 +32000范围
    推荐使用:存储相对比较小的整数。 比如: 年纪,数量
  • INT

    1
    2
    3
    字节:4
    描述:整数,从-2000000000 到 +2000000000 范围
    推荐使用: 存储中等整数 例如: 距离
  • BIGINT

    1
    2
    3
    字节:8
    描述:不能用SMALLINT 或 INT描述的超大整数。
    推荐使用:存储超大的整数 例如: 科学/数学数据

2.FLOAT

  • FLOAT

    1
    2
    3
    字节:4
    描述:单精度浮点型数据
    推荐使用:存储小数数据 例如:测量,温度
  • DOUBLE

    1
    2
    3
    字节:8
    描述:双精度浮点型数据
    推荐使用:需要双精度存储的小数数据 例如:科学数据
  • DECIMAL

    1
    2
    3
    字节:变量;取决于精度与长度
    描述:用户自定义精度的浮点型数据
    推荐使用:以特别高的精度存储小数数据。 例如:货币数额,科学数据

3.CHAR

  • CHAR

    1
    2
    3
    字节:特定字符串长度(高达255字 符)
    描述:固定长度的字符串
    推荐使用:存储通常包含预定义字符串的变量 例如: 定期航线,国家或邮编
  • VARCHAR

    1
    2
    3
    字节:变量; 1 + 实际字符串长度 (高达 255 字 符)
    描述:具有最大限制的可变长度的字符串
    推荐使用:存储不同长度的字符串值(高达一个特定的最大限度). 例如:名字,密码,短文标签
  • TEXT

    1
    2
    3
    字节:Variable; 2 +聽 actual string length
    描述:没有最大长度限制的可变长度的字符串
    推荐使用:存储大型文本数据,例如: 新闻故事,产品描述
  • BLOB

    1
    2
    3
    字节:变量;2 + 实际字符串长度
    描述:二进制字符串
    推荐使用:存储二进制数据 例如:图片,附件,二进制文档

4.TIME

  • DATE

    1
    2
    3
    字节:3
    描述:以 yyyy-mm-dd格式的日期
    推荐使用:存储日期 例如:生日,产品满期
  • TIME

    1
    2
    3
    字节:3
    描述:以 hh:mm:ss格式的时间
    推荐使用:存储时间或时间间隔 例如:报警声,两时间之间的间隔,任务开始/结束时间
  • DATETIME

    1
    2
    3
    字节:8
    描述:以yyyy-mm-ddhh:mm:ss格式结合日期和时间
    推荐使用:存储包含日期和时间的数据 例如:提醒的人,事件
  • TIMESTAMP

    1
    2
    3
    字节:4
    描述:以yyyy-mm-ddhh:mm:ss格式结合日期和时间
    推荐使用:记录即时时间 例如:事件提醒器,“最后进入”的时间标记
  • YEAR

    1
    2
    3
    字节:1
    描述:以 yyyy格式的年份
    推荐使用:存储年份 例如:毕业年,出生年

5.集合

  • ENUM

    1
    2
    3
    字节:1或 2个字节
    描述:一组数据,用户可从中选择其中一个
    推荐使用:存储字符属性,只能从中选择之一 例如:布尔量选择,如性别
  • SET

    1
    2
    3
    字节:从1到8字节;取决于设置的大小
    描述:一组数据,用户可从中选择其中0,1或更多。
    推荐使用:存储字符属性,可从中选择多个字符的联合。 例如:多选项选择,比如业余爱好和兴趣

Mysql 连接数据库

数据库的连接 for Mysql

格式:mysql -u<用户名> -p<密码>
或者
格式:mysql -u<用户名> -p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.7.11 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Git 获取远端分支

将远程分支信息获取到本地

1
$ git fetch

将远程分支映射到本地

1
2
3
4
5
6
7
$ git checkout -b changeCodeStruct_local origin/changeCodeStruct
Branch changeCodeStruct_local set up to track remote branch changeCodeStruct from origin.
Switched to a new branch 'changeCodeStruct_local'
$ git branch
* changeCodeStruct_local
dev
master

结束

这样就可以把远端的分支获取到了。

KVC 键值设置编码的行为

调用的过程

以属性 name 来说明

  1. 接收器中有setName:的访问器(或者是 _setName)就调用它
  2. 没有访问器,则使用接收器的类方法 accessInstanceVariablesDirectly ,返回 YES 时,如果存在实例变量 name (或者 _name, isName, _isName 等)就设定值。如果使用计数引用,那么旧值就会被释放啦,新的被保存并带入
  3. 如果都不行,就会调用 setValue:ForUndefinedKey:
  4. 返回的值如果不是对象,则切换到合适的值。

方法

1
2
3
4
5
6
7
8
9

/**
不能设置键字符串 key 时,从 setValue:forKey 中调用这个方法。默认情况下
会触发异常 NSUndefinedKeyException
在子类的定义中修改就可以返回其他对象了

*/

-(void)setValue: (id)value
forUndefinedKey: (NSString *)key

KVC 键值访问编码的行为

调用的过程

以属性 name 来说明

  1. 接收器中有name的访问器(或者是 getName, isName, _name, _getName)就调用它。
  2. 没有访问器,则使用接收器的类方法 accessInstanceVariablesDirectly 来确定是否(YES / NO)可以返回值
  3. 如果都不行,就会调用 valueForUndefinedKey:
  4. 返回的值如果不是对象,那么返回被适当的封装的对象。

方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
通常定义为返回 YES,可以在子类中改变。
返回 YES 时,说明可以访问实例变量
返回 NO 时,不可以访问
即使为 @Private 也可以访问

*/

+ (BOOL) accessInstanceVariablesDirectly
/**
不能取得键字符串的值时,从方法 valueForKey: 中调用该方法
默认情况下会触发异常 NSUndefinedKeyException
在子类的定义中修改就可以返回其他对象了

*/

- (id) valueForUndefinedKey:(NSString *)key

IOS Key-Value Code 的基本操作

简单说一下

键值编码必须的方法在非正式协议 NSKeyValueCoding 中声明 <Foundation/NSKeyValueCoding.h>
默认在 NSObject 中实现。

这样我们可以不用通过访问器去访问和设置属性。

我们可以通过属性的字符串名称访问设置 它。


两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

/**
返回表示属性的键字符串相应的值,如果没有将会调用 valueForUndefinedKey: 的方法。
@ param key 属性的键字符串
*/

- (id) valueForKey:(NSString *) key

/**
设置键字符串对应的值为value,如果不能将会调用方法 setValue:ForUndefinedKey:

@param value 要设置的值
@param key 属性的键字符串
*/

- (id) setValue: (id)value
forKey: (NSString *) key

简单的实验证明

代码例子

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
36
37
38
39
40
41
42
43
44
45
46
47
#import <Foundation/Foundation.h>

@interface Person: NSObject // Use ARC
{
NSString *name; // Person 的 name 属性
NSString *email; // Person 的 email 属性
int age;
}
- (void)setName:(NSString *)aName;
- (NSString *)email;
@end

@implementation Person

- (void)setName:(NSString *)aName
{
NSLog(@"Access: setName:");
name = aName;
}

- (NSString *)email
{
NSLog(@"Access: email:");
return email;
}

@end

int main(void)
{

static NSString *keys[] = {@"name", @"email", @"age", nil};
@autoreleasepool {
id obj = [[Person alloc] init];

/* setValue:forKey: */
[obj setValue:@"Taro" forKey:@"name"];
[obj setValue:@"tar@ryugu-jo" forKey:@"email"];
[obj setValue:[NSNumber numberWithInt:16] forKey:@"age"];

/* valueForKey: */
for (int i=0; keys[i]; i++)
NSLog(@"%@: %@", keys[i], [obj valueForKey:keys[i]]);
}

return 0;
}

编译文件

1
2
3
$ clang kvcsimple.m -framework Foundation
$ ls
a.out kvcsimple.m

结果显示

1
2
3
4
5
6
$ ./a.out
2016-03-13 10:05:36.105 a.out[656:17248] Access: setName:
2016-03-13 10:05:36.106 a.out[656:17248] name: Taro
2016-03-13 10:05:36.106 a.out[656:17248] Access: email:
2016-03-13 10:05:36.106 a.out[656:17248] email: tar@ryugu-jo
2016-03-13 10:05:36.107 a.out[656:17248] age: 16

软件下载的网站

国外的比较好的下载软件的网站

国内软件下载的网站