Objective-C基础教程读书笔记

来源:互联网 发布:汽车导航升级软件 编辑:程序博客网 时间:2024/06/05 01:09

第二章 对C的扩展

1.#import,让编译器引入一次头文件(且仅引入一次)。

2.@符号,Objective-C对C的扩展。

第三章 面向对象编程基础知识

1.中缀符(infix notation),方法的名称及参数都是合在一起的;它使代码的可读性更强,更容易理解参数的用途。

2.实例化(instantiation),创建和初始化对象的过程;实例化对象时,需要分配内存,然后这些内存被初始化并保存一些有用的默认值。

第四章 继承

1.基地址加偏移,给定的对象基地址,是指第一个实例变量的首个字节在内存中的位置。通过在该地址加上偏移地址,编译器就可以查找其他实例变量的位置。

第六章 源文件组织

1.@class,告诉编译器:“这是一个类,所以我只需要通过指针来引用它。”

第八章 Foundation Kit快速教程

1.类对象,Objective-C运行时生成一个类的时候,它会创建一个代表该类的类对象。类对象包含了指向超类的指针、类名和指向类方法列表的指针。类对象还包含一个long型数据,为新创建的类实例对象指定大小(以字节为单位)。

2.类方法,如果你在声明方法时添加了加号,那么就是把这个方法定义为类方法。这个方法属于类对象(而不是类实例对象)并且通常用于创建新的实例。我们称这种用于创建新对象的类方法为工厂方法

第九章 内存管理

Cocoa中关于对象及其保留计数器的3条原则:

1.如果使用new,alloc或copy操作获得一个对象,则该对象的保留计数值为1。

2.如果通过任何其他一个方法获得对象,则假设该对象的保留计数器值为1,而且已经被设置为自动释放。

3.如果保留了某个对象,则必须保持retain方法和release方法的使用次数相等。

第十二章 类别

类别是一个为现有类添加新方法的方式。

1.局限性:第一,无法向类中添加新的实例变量。类别没有位置容纳实例变量;第二,名称冲突,即类别中的方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。

2.作用:将类的实现分散到多个不同的文件或多个不同的框架中,创建对私有方法的前向引用,以及向对象添加非正式协议。

不但可以将一个类的实现分散到多个不同的源文件中,还可以将其分散到多个不同的框架中。

3.委托(delegate)是一种对象,另一个类的对象会要求委托对象执行它的某些操作。

4.创建一个NSObject的类别称为“创建一个非正式协议”。

第十五章 文件加载和保存

文件加载和保存的方式,集合属性列表和编码对象。

集合属性列表类(NSArray、NSDictionary)具有一个-writeToFile:atomically:方法,用于将属性列表写入文件。NSString和NSData也具有-writeToFile:atomically:方法,但它只能写入字符串或数据块。

编码对象:使用NSCoding协议。采用该协议,可以实现这两种方法-encodeWithCoder和-initWithCoder,当对象需要保存自身 时,-encodeWithCoder方法将被调用;当对象需要加载自身时,-initWithCoder:方法将被调用。

-initWithCoder:和任何其他init方法一样,在对对象执行操作之前,需要使用超类对它们进行初始化。

我们将使用NSKeyedArchiver把对象归档到NSData中。

NSData *freezeDried;

freezeDried = [NSKeyedArchiver archivedDataWithRootObject: thing1];

使用NSKeyedUnarchiver解压 归档后的NSData对象。

thing1 = [NSKeyedUnarchiver unarchivedObjectWithData: freezeDried];

Cocoa的归档程序和解压程序实现上非常灵活,能检测对象循环,能够保存并恢复对象周期。

第十六章 键/值编码

1.KVC简介

    1.1键/值编码中的基本调用包括-valueForKey:和-setValue:ForKey:。以字符串的形式向对象发送消息,这个字符串是我们关注的属性的关键。

我们可以请求car的名称:

NSString *name = [car valueForKey:"name"];(name是car对象中的变量名)

valueForKey首先查找以键-key或-isKey命名的getter方法。如果不存在getter方法,它将在对象内部查找名为_key或key的实例变量。

非常重要:-valueForKey在Objective-C运行时中使用元数据打开对象并进入其中查找需要的信息。

KVC具有自动包装功能,也仅KVC具有。

       setValue:ForKey: 和valueForKey:相同,它首先查找名称的setter方法;使用它设置一个标量值之前,需要将其包装成对象。

1.2路径

可以指定以圆点分隔的不同属性名称。这样,通过查询car的“engine.horsepower”,就能够获取马力值,使用方法valueForKeyPath。

键路径的深度是任意的,具体取决于对象图(对象图是一种表示相关对象集合的有趣方式)的复杂度。

1.3流畅地运算

可以引用一些运算符来进行一些运算。

如:NSNumber *count = [garage valueForKeyPath:@"cars.@count"];

@count用于通知KVC机制计算键路径左侧的结果。

NSNumber *sum = [garage valueForKeyPath:@"cars.@sum.millage"];计算某些特定值的总和;@avg平均值。

还有@min和@max运算符,它们的功能很明显。

使用@distinctUnionOfObjects获取互不相同的一组对象。

1.4生成NSDictionary。

car = [[garage valueForKeyPath: @"cars"] lastObject];

NSArray *keys = [NSArray arrayWithObjects: @"make", @"model", @"modelYear", nil];

NSDicitionary *carValues = [car dictionaryWithValuesForKey: keys];

     生成一个新的car。

NSDictionary *newValues = [NSDicitionary dictionaryWithObjectsAndKeys:@"Chevy", @"make",

    @"Nova", @"model",

    [NSNumber numberWithInt:1964], @"modelYear",

    nil];

[car setValuesForKeysWithDictionary:newValues];

1.5标量值的nil,重写setNilValueForKey。

1.6处理未定义的键,重写valueForUndefinedKey和setValue:forUndefineKey方法。

    <null>是一种[NSNull null]对象,而(null)是一个真实存在的nil值。

如果在字典中将setValue:ForKey:设置为nil值,将会把对应的键从字典中删除。

第十七章 NSPredicate

1.创建谓词:NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == ‘Herbie'"];

2.计算谓词:BOOL match = [predicate evaluateWithObject : car];接收对象为car,使用name作为键路径,应用valueForKeyPath:方法获取名称;然后它将自身的值与“Herbie"相比较。

3.另一个谓词:predicate = [NSPredicate predicateWithFormat:@"engin.horsepower > 150"];

   match = [predicate evaluateWithObject: car];

4.燃料过滤器:-filteredArrayUsingPredicate:是NSArray数组中的一种类别方法,它将循环过滤数组内容,根据谓词计算每个对象的值,并将值为YES的对象累计到将被返回的新数组中:

NSArray *results = [cars filteredArrayUsingPredicate:predicate];

5.格式说明符:predicate = [NSPredicate predicateWithFormat: @"engine.horsepower > %d", 50];

也可以使用%K指定键路径,predicate = [NSPredicate predicateWithFormat: @”%K == %@“, @"name", @"Herbie"];

6.变量名:将变量名放入字符串中,类似于环境变量:NSPredicate = [NSPredicate predicateWithFormat: @"name == $NAME"];

创建一个键/值对字典,其中,键是变量名(不包含美元符号$),值是插入谓词的内容,代码如下所示:

NSDictionary *varDict = [NSDictionary dictionaryWithObjectsAndKeys: @"Herbie", @"NAME", nil];

现在可以使用predicateWithSubstitutionVariables调用来构造新的专用谓词:

predicate = [prediateTemplate predicateWithSubstitutionVariables:varDict];

不能用$VARIABLE作为键路径,因为它只表示值。

7.运算符

   7.1比较和逻辑运算符:谓词字符串语法支持C语言中一些常用的运算符,例如等号运算符==和=,不等号运算符>、=>和>=、<、<=和=<、!=和<>。

    谓词字符串语法还支持括号表达式和AND、OR、NOT逻辑运算符或者C语言样式的等效表达式&&、|| 和!。

  7.2数组运算符:介于50和200之间,可以使用BETWEEN { 50, 200}表示,花括号表示数组。也可以使用%@格式说明符插入你自己的NSArray对象。

数组并不仅仅用来指定某个区间的端点值。你可以使用IN运算符查找是否含有数组中某个特定的值,如 “name IN {'Herbie', 'Snugs', 'Badger', 'Flap'}";

8.SELF足够了

假如我们有一个汽车名称数组,并且需要应用前面相同的过滤器。从NSString 对象中查询name时,将不能起到预期效果,那么,我们用什么来代替name呢?

用SELF来解决。

NSArray *names = [cars valueForKey:"name"];

predicate = [NSPredicate predicateWithFormat:@”SELF in {'Herbie', 'Snugs', 'badger', 'Flap'}"];

计算该谓词的值:results = [names filteredArrayUsingPredicate:predicate];

此方法也可以用来取两个数组的交集。

9.字符串运算符

BEGINSWITH:检查某个字符串是否以另一个字符串开头。

ENDSWITH:检查某个字符串是否以另一个字符串结尾。

CONTAINS:检查某个字符串是否在另一个字符串内部。

字符串匹配是区分大小写的;为了减少名称匹配规则,可以为这些运算符添加[c]、[d]或[cd]修饰符;其中c表示“不区分大小写”,d表示“不区分发音符号”,

[cd]表示不区分二者。

该谓词字符串会将Herbie与"name BEGINSWITH[cd] ’HERB‘“相匹配。

10.LIKE运算符

在LIKE运算符中,问号表示与一个字符匹配,星号表示与任意个字符匹配。

谓词字符串"name LIKE '*er*'"将会与任何含有"er"的名称相匹配。这等效于CONTAINS。

11.使用MATCHES运算符,赋给该运算符一个正则表达式,谓词将会计算出它的值。(表达自己:NSPredicate正则表达式使用International Components for Unicode(ICU)语法。)正则表达式的计算开销非常大,在使用MATCHES之前可以先执行简单的运算,这样将会提高程序的运算速度。



原创粉丝点击