1argc为启动参数个数,因为启动参数第一个是工程名称,所以argc必大于等于1
2可以在方法中的注释哩加入以TODO: MARK: FIXME: ???:等开头的文本,这些作为程序员所做的记号放入到功能菜单中。
3runloop一直处于阻塞状态,直至某些有趣的事情发生为止。
4非正式协议是NSObject的一个类别。它能够列出对象能够响应的方法。
5文件加载与保存:Cocoa提供了两个通用的文件处理类,属性列表和对象编码
Cocoa中有一类名为属性列表的对象,常写为plist。属性列表包含Cocoa知道如何操作的一组对象。
NSArray、NSDictionary、NSString、NSData都有-writeToFile:atomically方法其中的atomically其实算是一种安全机制,其通知Cocoa是否应该首先将文件内容保存在临时文件中。当文件保存成功后,再降该临时文件盒原始文件交换。但这需要使用双倍的磁盘空间。
对于那些非属性列表譬如自己创建的对象,就要使用编码和解码,也称作序列化和反序列化。
@protocol NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
@end
当自定义类实现了以上协议,就可以在别的类中序列化和反序列化当前类了。
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:selfObject]
selfObject = [NSKeyedArchiver unarchivedDataWithData:data];
6键值编码(可以在更高的抽象级别上和对象交互)
valueForKey:首先查找getter方法,如果没有getter方法,就直接查找实例变量,取值。
setValue:forKey:同上,首先查找setter方法,若没有,则查找实例变量,为其赋值。
路径:car.interior.airconditioner.fan.velocity也是可以的,使用键路径比使用一些列嵌套方法调用更容易访问对象。valueForKeyPath:
如果向NSArray请求一个键值,实际上会查询数组中的每个对象来查询键值。
可使用KVC进行一些计算,然而并不是免费的,KVC需要解析字符串来计算你需要的答案,因此速度比较慢,此外,编译器无法对它进行错误检查。计算的运算符譬如cars.@count,cars.@sum.mileage,cars.@avg.mileage。还有一个@distinctUnionOfObjects。
可通过dictionaryWithValuesForKey:和setValuesForKeysWithDictionary:来进行批处理。
可通过重写setNilVauleForKey:来处理setValue:forKey设置nil的情况。
可通过重写setValue:forUndefinedKey和valueForUndefinedKey来处理未定义的键。
<null>是一种[NSNull null]对象,而(null)是一个真实存在的nil值。如果为NSDictionary的setObject:forKey提供nil值,它将会给出警告信息。但是如果setValue:forKey给出nil值,将会把对应的键从字典里删除。
[site setValue:@"sitename" forKey:@"name"];
//会被编译器处理成
SEL sel = sel_get_uid(setValue:forKey);
IMP method = objc_msg_loopup(site->isa,sel);
method(site,sel,@"sitename",@"name");
每一个类都有一张hash表,键是SEL,值是函数指针IMP。
7NSPredicate(谓词)
创建:NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=='Herbie'"];//注意这里Herbie用单引号扩上
计算:BOOL match = [predicate evaluateWithOBject:car];
以上步骤其实是接收对象是car,使用name作为键路径,引用valueForKeyPath:方法获取名称,然后将自身值与Herbie比较得到结果。
过滤器:某些类别也将谓词过滤方法填到了Cocoa集合类中。NSArray就有filteredArrayUsingPredicate:还有filterUsingPredicte:
谓词中的各式说明符:
同stringWithFormat相同%d,%@等,也可以通过%K指定键路径。
也可以构造含有变量的谓词:
NSPredicate *predicateTmp = [NSpredicate predicateWithFormat:@"engine.horsepower>$POWER"];
varDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:150],@"POWER",nil];
predicate = [predicateTmp predicateWithSubstitutionVariables:varDict];
predicate即为新创建的谓词。
注意:谓词机制不进行类型检查。
比较合逻辑运算符:AND、OR、NOT
数组运算符:NSPredicate *predicate = [NSpredicate predicateWithFormat:@"engine.horsepower BETWEEN{50,200}"];
SQL语句中的IN预算符:NSPredicate *predicate = [NSpredicate predicateWithFormat:@"name IN {"Herbie","Snugs","Badger","Flap"}"];
SELF:
字符串运算符:BEGINSWITH\ENDSWITH\CONTAINS,譬如:name BEGINSWITH[cd] 'HERB';其中c表示不区分大小写,d表示不区分发音符号。
LIKE运算符:*表示与任意字符串相配,?表示与一个字符匹配。LIKE也接受cd字符。譬如 name LIKE '*er*'。
正则表达式:MATCHES运算符。注意:正则表达式虽然功能强大,但是计算开销非常大。
8暴力调试:在程序中放入输出语句(如NSLog)来输出程序的控制流程和一些数据值。
10一些快捷键
esc或control+.(顺序循环)或shift+control+.(逆序循环): 显示代码提示菜单
control+/移动代码到提示中的下一个占位符
control+f前移光标 control+b后移光标
11枚举
枚举器- (NSEnumerator *)objectEnumerator;
快速枚举for (NSString *string in array)它比枚举器语法更加简洁快速
12NSDictionary也成为散列表或关联数组,使用的是键查询的优化存储方法。实际上字典非常快。
13关于类族:NSString或NSArray的使用者不用在意系统内部到底用的是哪个类。尽量使用,但是不要扩展。
14@encode(),根据传入的类型,得到预期对应的c编码字符串
NSLog(@"%s",@encode(double));
NSNumber *num = [NSNumber numberWithDouble:1.2f];
NSLog(@"%s",[num objCType]);//objCType是NSValue的一个方法