怎么理解公式5.5C是指圆的周长公式吗,还有根号下面的内容怎么理解

该文章转载自:一:Objective-C入门
1、Cocoa的组成
苹果公司将Cocoa、Carbon、QuickTime和OpenGL等技术作为框架集提供
Cocoa组成部分有:
Foundation框架(有很多有用的,面向数据的低级类和数据结构)
Application Kit(也称AppKit)框架(包含了所有的用户接口对象和高级类,例如NS&&)
,还有一个支持框架的套件,包括Core Animation和Core Image。
2、NSLog相当于printf()
NSLog(@"hello Objective-C");
//注:@是Objective-C在标准C语言基础上添加的特征之一,双引号的字符串前面有一个@,这表示引用的字符串应该作为Cocoa的NSString元素处理
NSLog(@"are %d and %d different? %@",5,5,boolString(areTheyDifferent));
//注意%@:使用NSLog输出任何对象值时,都会使用这个格式说明
3、BOOL使用8位存储,YES定义为1,NO定义为0,大于1不为YES,跟标准C不同。
若不小心将一个长于1字节的整型值赋给BOOL,则只截取低八位
Obejective-C中1不等于1,绝对不要将BOOL值和YES比较
二:面向对象的Objective-C
4、使用间接从本地读取文件的例子
#import &Foundation/Foundation.h&
int main(int argc,const char * argv[]) {
if(argc == 1){
NSLog(@"you need to provide a file name");
return (1);
FILE *wordFile = fopen(argv[1] , "r");
char word[100];
while (fgets(word,100,wordFile)){
//fget调用会保留分开每一行的换行符,我们不需要,把它替换为0,表示字符串的结束
word[strlen(word)-1] ='\0';
NSLog(@"%s is %d characters long",word,strlen(word));
//运行用 ./Word-Length-4 /tmp/words.txt
若给了文件路径,那么argc会大于1,然后我们可以查询argv数组得到文件路径。argv[1]保存着用户提供的文件名,argv[0]保存着程序名。
在XCode中编译此程序需要在XCode文件列表中展开Executables,双击程序名,在Arguments区域中添加启动参数
id是一种泛型,用于表示任何类的对象,id实际上是一个指针,指向其中的某个结构
例[shape draw]
第一项是对象名,其余部分是要执行的操作
7、Objective-C的OOP范例
1)@interface部分(一般都作为.h单独书写,声明部分)
@interface Circle:NSObject
//说明这是为Circle的新类定义的接口
ShapeColor fillC
//括号内的是Circle对象需要的各种数据成员
- (void) setFilColor:(ShapeColor) fillC
//先行短线表明&这是新方法的声明&如果是&+&则表示是类方法,也称工厂方法
- (void) setBounds:(ShapeRect)
2)@implementation部分(一般写为.m文件,实现部分)
@implementation Circle
//@implementation是一个编译器指令,表明你将为某个类提供代码
- (void) setFillColor:(ShapeColor) c
//在这里如果继续使用参数名fillColor,就会隐藏fillColor实例变量,并且有警告
//我们已经定义了一个名为fillColor的实例变量,可以在该方法中引用该变量,如果使用相同的另一个变量,那么前一个会屏蔽
fillColor =
- (void) setBounds:(ShapeRect) b
- (void) draw
NSLog("^^^")
@end //Circle
可以在@implementation中定义那些在@interface中无相应声明的方法,可以把他们看做是石油方法,仅在类的实现中使用。
注:Objective-C不存在真正的私有方法,从而禁止其他代码调用它。这是Objective-C动态本质的副作用。
8、中缀符(infix natation)
方法的名称和及其参数都是合在一起的
一个参数:
[citcle setFillColor : KRedColor];
两个参数:
[circle setStringValue : @&hello there& color : KBlueColor];
9、继承(X是一个Y,isa)
1)Objective-C不支持多继承,我们可以通过Objective-C的其他特性获取多继承的优点,例如分类和协议
2)继承中方法的定义
可以使用空正文和一个虚(dummy)值都是可以的
3)方法调度
当代码发送消息时,Objective-C的方法调度将在当前分类中搜索相应的方法,如果找不到,则在该对象的超类中进行查找
4)实例变量
10、复合(X有一个Y,has)
严格的讲,只有对象间的组合才叫做复合,诸如int、float、enum和struct等基本类型都认为是对象的一部分
- (id) init
if (self = [super init]) { //将[super init]得结果赋给self是Objective-C的标准惯例,为了防止超类的初始化过程中返回的对象不同于原先创建的对象
//若要超类要完成所需的一次性初始化,需要调用[super init],init方法返回的值描述了被初始化的对象
engine = [Engine new];
tires[0] = [Tire new];
tires[1] = [Tire new];
tires[2] = [Tire new];
tires[3] = [Tire new];
return (self);
12、存取方法(accessor method)
setter和getter
setter方法根据他所要更改的属性的名称来命名,并加上set
getter方法根据其返回的属性的名称来命名,不要加get
三:源文件组织
13、@class * 和import *.h
@class创建一个类前声明,告诉编译器:相信我,以后你会知道这个到底是什么,但是现在,你只需要知道这些
继承一个类的时候不能用@class,因为他们不是通过指针指向其他类,所以继承一个类时要用import *.h
四:Xcode的使用
14、更改自动注释中的公司名
defaults write com.apple.apple.Xcode PBXCustomTemplateMacroDefinitions
'{&ORGANIZATIONNAME& = &iPhone_xiaoyuan.com&;}&
没有任何输出结果
15键盘符号
1)Mac按键符号
2)Microsoft键盘和Mac键盘的对照
徽标键-&Option
16、Xcode技巧
1)同步显示
有时候两个窗口中显示的内容并不是同步的,只有分别单击了它们,才能同步更新内容
2)首行缩进
选自,右键-&Re-indent selection
Alt [ 和 Alt ]可以把选中的代码左移和右移
3)代码自动完成
Tab 键可以按频率最高的填充完成词
Esc 可以弹出提示列表(E表示枚举,f代表函数,#代表@define,m表示方法,C表示类)
Ctl+. 在各选项中切换
Shift+Ctrl+. 反向循环
control+/ 在占位符之间切换
4)批量编辑
快照:File-&Make Snapshot
查看快照:File-&Snapshot
一次改变文件中的相同字符:选定,Edit-&Edit all in Scope,更改的时候都会变
重构:选定,Edit-&Refactor,弹出对话框,输入要改成的字符(选中Snapshot后可以看见改变)
5)键盘代替鼠标
■ control-F: Move forward, to the right (same as the right arrow).
■ control-B: Move backwards, to the left (same as the left arrow).
■ control-P: Move to the previous line (same as the up arrow).
■ control-N: Move to the next line (same as the down arrow).
■ control-A: Move to the beginning of a line (same as the as command- left arrow).
■ control-E: Move to the end of a line (same as the as command- right arrow).
■ control-T: Transpose (swap) the characters on either side of the cursor.
■ control-D: Delete the character to the right of the cursor.
■ control-K: Kill (delete) the rest of the line. This is handy if you want to redo the end of a line of code.
■ control-L: Center the insertion point in the window. This is great if you&ve lost your text cursor or want to quickly scroll the window so the insertion point is front and center.
6)任意搜索
在菜单栏上面搜索
7)快速打开
#import后的文件选中,File-&Open Quickly,Xcode就会打开文件。若不选择,则会打开Open Quickly对话框
8)打开文档
Option+双击
9)调试时看数据
鼠标放在上面一会就可以看到
五:Foundation Kit
17、一些有用的数据结构 (结构体能减少过程中的开销)
//用来表示相关事物的范围
typedef struct _NSRange {
unsigned int
unsigned int
例如&Objective-C is a cool language&中,&cool&可以用location为17,length为4的范围来表示
有3种方式可以创建新的NSRange
第一种:直接给字段赋值
range.location = 17;
range.length = 4;
第二种:应用C语言的聚合结构赋值机制
NSRange range = { 17, 4 };
第三种:使用Cocoa提供的快捷函数NSMakeRange():
NSRange range = NSMakeRange(17,4);
//使用NSMakeRange()的好处是可以在任何使用函数的地方使用他
//例如 [anObject flarbulateWithRange: NSMakeRange (13, 15)];
2)几何数据类型
typedef struct _NSPoint {
typedef struct _NSSize {
typedef struct _NSRect {
//Cocoa也为我们提供了这些类型的快捷函数:NSMakePoint()、NSMakeSize()和NSMakeRect()
18、字符串(NSString和NSMutableString)
A:不可变的字符串(NSString)
1) 创建不可变的字符串
函数:+ (id) stringWithFormat: (NSString *) format, ...;
使用方法:
NSString *
height = [NSString stringWithFormat:@"Your height is %d feet, %dinches", 5, 11];
2)NSString类中的方法
函数:- (unsigned int)
使用方法:
if ([height length] & 35) {
NSLog (@"wow, you're really tall!");
函数1:- (BOOL) isEqualToString: (NSString *) aS
使用方法:
NSString *thing1 = @"hello 5";
NSString *thing2;
thing2 = [NSString stringWithFormat: @"hello %d", 5];
if ([thing1 isEqualToString: thing2]) {
NSLog (@"They are the same!");
} //应用这个函数,不能用&==&,&==&只能比较字符串的指针值
函数2:- (NSComparisonResult) compare: (NSString *) string;
typedef enum _NSComparisonResult {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
} NSComparisonR
使用方法:
[@"aardvark" compare: @"zygote"]
return NSOrderedAscending:.
[@"zoinks" compare: @"jinkies"]
return NSOrderedDescending. And,
[@"fnord" compare: @"fnord"]
return NSOrderedSame.
不区分大小写的比较
函数: - (NSComparisonResult) compare: (NSString *) string
options: (unsigned)
options参数是一个位掩码,可以用位或运算符(|)来添加这些选项标记
一些常用的标记有
■ NSCaseInsensitiveSearch: 不区分大小写
■ NSLiteralSearch: 进行完全比较,区分大小写
■ NSNumericSearch:比较字符串的字符个数,而不是字符值,若没项,&100&会排在&99&前面(一定要加)
使用方法:
if ([thing1 compare: thing2 options: NSCaseInsensitiveSearch | NSNumericSearch]== NSOrderedSame) {
NSLog (@"They match!");
③ 包含字符串判断
- (BOOL) hasPrefix: (NSString *) aS
//判断开头
- (BOOL) hasSuffix: (NSString *) aS
//判断结尾
- (NSRange) rangeOfString: (NSString *) aS //看字符串中是否包含其他字符串
使用方法:
NSString *filename = @"draft- chapter.pages";
if ([fileName hasPrefix: @"draft") {
// this is a draft
if ([fileName hasSuffix: @".mov") {
// this is a movie
range = [fileName rangeOfString: @"chapter"];
//返回range.start为6,range.length为7,若传递的参数在接受字符串中没有找到,那么range.start则等于NSNotFound
B)可变字符串(NSMutableString)
1)创建可变的字符串
函数:+ (id) stringWithCapacity: (unsigned) //这个容量只是给NSMutableString的一个建议
使用方法:
NSMutableString *string;
string = [NSMutableString stringWithCapacity: 42];
继承NSString中的方法
NSMutableString *string;
string = [NSMutableString stringWithFormat: @"jo%dy", 2];
2)NSMutableString中的方法
- (void) appendString: (NSString *) aS
- (void) appendFormat: (NSString *) format, ...;
- (void) deleteCharactersInRange: (NSRange) //配合rangeOfString:一起连用
使用方法:
NSMutableString *string;
string = [NSMutableString stringWithCapacity: 50];
[string appendString: @"Hello there"];
[string appendFormat: @"human %d!",39];
NSMutableString *
friends = [NSMutableString stringWithCapacity: 50];
[friends appendString: @"James BethLynn Jack Evan"];
NSRange jackR
jackRange = [friends rangeOfString: @"Jack"];
jackRange.length++;
// eat the space that follows
[friends deleteCharactersInRange: jackRange];
19、NSArray和NSMutableArray
A) NSArray(不可改变的数组,是一个Cocoa类,用来存储对象的有序列表)
NSArray的两个限制
首先:它只能存储Objective-C的对象,而不能存储C语言中的基本数据类型,如:int, float, enum, struct,或者是NSArray中的随机指针
然后:不能存储nil
1)创建方法
通过类的方法arrayWithObjects:创建一个新的NSArray
使用方法:
array = [NSArray arrayWithObjects:@"one", @"two", @"three",nil];
//array是以nil结尾的,这是nil不能存储的原因
2)常用方法
- (unsigned) //获取数组包含的对象个数
- (id) objecAtIndex : (unsigned int) //获取特定索引处的对象
- componentsSeparatedByString://切分NSArray
- componentsJoinedByString://合并NSString
使用方法:
for (i = 0; i & [array count]; i++) {
NSLog (@"index %d has %@.",i, [array objectAtIndex: i]);
NSString *string = @"oop:ack:bork:greeble:ponies";
NSArray *chunks = [string componentsSeparatedByString: @":"];
string = [chunks componentsJoinedByString: @" :- ) "];
B)NSMutableArray(可变数组)
1)创建方法,通过类方法arrayWithCapacity创建
+ (id) arrayWithCapacity: (unsigned) numI
使用方法:
NSMutableArray *
array = [NSMutableArray arrayWithCapacity: 17];
2)常用方法
- (void) addObject: (id) anO
- (void) removeObjectAtIndex: (unsigned)
使用方法:
for (i = 0; i & 4; i++) {
Tire *tire = [Tire new];
[array addObject: tire];
[array removeObjectAtIndex: 1]; //删除第二个
C)遍历数组的三种方式:通过索引、使用NAEnumerator和快速枚举
1)索引遍历
//只有在真的需要索引访问数组时才应使用-objectAtIndex,例如跳跃数组或者同时遍历多个数组时
for (i = 0; i & [array count]; i++) {
NSLog (@"index %d has %@.",i, [array objectAtIndex: i]);
2)使用NSEnumerator
//Leopard中被快速枚举替代
创建方法:通过函数 - (NSEnumerator *) objectE
NSEnumerator *
enumerator = [array objectEnumerator];
//如果想从后往前浏览集合,还有一个方法reverseEnumerator可以使用
创建后通过while循环,条件是nextObject( 方法原型 - (id) nextObject );
循环遍历的程序为:
NSEnumerator *
enumerator = [array objectEnumerator];
while(thingie = [enumerator nextObject ]) {
NSLog(@&i found %@& , thingie);
//注:对可变数组进行枚举操作时,不能通过添加和删除对象这类方式来改变数组容器,如果这样做了,枚举器会觉得困惑,为你将会得到未定义结果
3)快速枚举
在Leopard中才开始的,Tiger中不能用
for (NSString *string in array ) {
NSLog(@&i found %@& , string);
21、破除NSArray限制的方法
1)基本类型
a):Cocoa提供了NSNumber类来包装基本类型
+ (NSNumber *) numberWithChar: (char)
+ (NSNumber *) numberWithInt: (int)
+ (NSNumber *) numberWithFloat: (float)
+ (NSNumber *) numberWithBool: (BOOL)
使用方法:
NSNumber *numner;
number = [NSNumber numberWithInt: 42];
[array addObject: number];
[dictionary setObject : number foyKey : @&Bork&];
只要将一些基本类型封装到NSNumber中,就可以通过下面的实例方法重新获得其值
- (char) charV
- (int) intV
- (float) floatV
- (BOOL) boolV
- (NSString *) stringV //允许自动转换
Objective-C不支持自动装箱,要自己动手
b):NSNumber是NSValue的子类,NSValue可以包装任意值
创建新的NSValue
+ (NSValue *) valueWithBytes: (const void *) value
objCType: (const char *)
使用方法:
NSRect rect = NSMakeRect (1, 2, 30, 40);
value = [NSValue valueWithBytes: &rect
objCType: @encode(NSRect)];
//encode编译器指令可以接受数据类型的名称并为你生成合适的字符串
[array addObject: value];
可以使用getValue:来提取数值(注意是get方法,指针)
- (void) getValue: (void *) //调用时,要传递的是要存储这个数值的变量的地址
value = [array objectAtIndex: 0];
[value getValue: &rect];
Cocoa提供了常用的struct型数据转换成NSValue的便捷方法
+ (NSValue *) valueWithPoint: (NSPoint)
+ (NSValue *) valueWithSize: (NSSize)
+ (NSValue *) valueWithRect: (NSRect)
- (NSPoint) pointV
- (NSSize) sizeV
- (NSRect) rectV
使用方法:
value = [NSValue valueWithRect: rect];
[array addObject: value];
NSRect anotherRect = [value rectValue];
NSNull大概是Cocoa里最简单的类了,只有一个方法
+ (NSNull *) null;
可以这样添加到集合中
[contact setObject: [NSNull null]
forKey: @"home fax machine"];
homefax = [contact objectForKey: @"home fax machine"];
if (homefax == [NSNull null]) {
// ... no fax machine. rats.
//[NSNull null]总是返回一样份数值,所以你可以使用&==&讲该值与其他值进行比较&&
22、NSDictionary和NSMutableDictionary
A) NSDictionary
字典是关键字和其定义的集合,也被成为散列表或关联数组,使用的是键查询的优化存储方式
1)创建方法: 使用dictionaryWithObjectsAndKeys:来创建字典
+ (id) dictionaryWithObjectsAndKeys: (id) firstObject, ...;
使用方法:
Tire *t1 = [Tire new];
Tire *t2 = [Tire new];
Tire *t3 = [Tire new];
Tire *t4 = [Tire new];
NSDictionary *
tires = [NSDictionary dictionaryWithObjectsAndKeys:
t1, @"front- left", t2, @"front- right",
t3, @"back- left", t4, @"back- right", nil];
2)常用方法
- (id) objectForKey: (id) aK
使用方法:
Tire *tire = [tires objectForKey: @"back- right"];
//如果没有则会返回nil值
B) NSMutableDictionary
1)创建方法:
可以向类NSMutableDictionary发送dictionary消息
也可以使用函数+ (id) dictionaryWithCapacity: (unsigned int) numI
2)常用方法
可以使用setObject:forKey:方法给字典添加元素:
- (void) setObject: (id) anObject forKey: (id) aK
- (void) removeObjectForKey: (id) aK
使用方法:
NSMutableDictionary *
tires = [NSMutableDictionary dictionary];
[tires setObject: t1 forKey: @"front- left"];
[tires setObject: t2 forKey: @"front- right"];
[tires setObject: t3 forKey: @"back- left"];
[tires setObject: t4 forKey: @"back- right"];
//若已经存在,则会用新值替换原有的值
[tires removeObjectForKey: @"back- left"];
23、不要创建NSString、NSArray或NSDictionary的子类,因为在Cocoa中,许多类实际上是以类簇的方式实现的,即他们是一群隐藏在通用接口之下的与实现相关的类
24、Foundation实例 //查找文件
A)使用枚举遍历
int main (int argc, const char *argv[])
NSAutoreleasePool *
pool = [[NSAutoreleasePool alloc] init];
//自动释放池
NSFileManager * //Cocoa中有很多类都是单实例构架,即只需要一个实例,你真的只需要一个文件管理器
manager = [NSFileManager defaultManager]; // defaultManager方法创建一个属于我们的NSFileManager对象
NSString *
home = [@"~" stringByExpandingTildeInPath]; // stringByExpandingTildeInPath方法可将~替换成当前用户的主目录
NSDirectoryEnumerator * //NSEnumerator的子类
direnum = [manager enumeratorAtPath: home]; //创建一个枚举条件
NSMutableArray *
files = [NSMutableArray arrayWithCapacity: 42]; //把搜索的结果作为文件存储
NSString *
while (filename = [direnum nextObject]) {//调用nextObject时,都会返回该目录中的一个文件的另一个路径,也可搜索子目录
if ([[filename pathExtension]
// pathExtension输出文件的扩展名(去掉了前面的点.)
isEqualTo: @"jpg"]) {
[files addObject: filename];
NSEnumerator *
fileenum = [files objectEnumerator];
while (filename = [fileenum nextObject]) {
NSLog (@"%@", filename);
[pool drain];
return (0);
B)使用快速遍历
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSFileManager *
manager = [NSFileManager defaultManager];
NSString *
home = [@"~" stringByExpandingTildeInPath];
NSMutableArray *
files = [NSMutableArray arrayWithCapacity: 42];
for (NSString *filename
in [manager enumeratorAtPath: home]) {
if ([[filename pathExtension]
isEqualTo: @"jpg"]) {
[files addObject: filename];
for (NSString *filename in files) {
NSLog (@"%@", filename);
六:内存管理
25、Cocoa采用引用计数(reference counting)的技术,有时称为保留计数。
每个对象有一个与之相关联的整数,称做为他的引用计数器或保留计数器
- (unsigned) retainC
26、对象所有权的处理
- (void) setEngine: (Engine *) newEngine
[newEngine retain];
[engine release];
engine = newE
} // setEngine
原则:先保存新对象,再释放员对象
27、自动释放
程序会自动建立一个自动释放池(autorelease pool),他是一个存放实体的池(集合),这些实体可能是对象,能够被自动释放。
自动释放池创建代码
NSAutoreleasePool
pool = [[NSAutoreleasePool
NSObject类提供了一个antorelease方法:
//该方法预先定义了一条在将来某个时间发送的release消息,其返回值是接收消息的对象,retain采用了相同的技术,使嵌套调用更加容易。
//当给一个对象发送autorelease消息时,实际上是将对象添加到NSAutoreleasePool方法中,当自动释放池销毁了,会像该池中的所有对象发送release消息
- (NSString *) description
NSString *
description = [[NSString alloc]
initWithFormat: @"I am %d years old", 4];
return ([description autorelease]); //因为descriptor方法首先创建了一个新的字符串对象,然后自动释放该对象,最后将其返回给NSLog()函数
} // description
29、Cocoa内存管理原则
如果使用new,alloc或copy操作获得一个对象,则该对象的保留计数器值加1,release减1
如果通过任何其他方法获得一个对象,则假设该对象的保留计数器值为1,而且已经被设置为自动释放
如果保留了某个对象,则必须保持retain方法和release方法使用的次数相同
30、NSColor的blueColor方法返回一个全局单例对象
31、一直拥有对象
希望在多个代码段中一直拥有某个对象常见的方法有:在其他对象中使用这些变量,将它们加入到诸如NSArray或NSDictionary等集合中,或将其作为全局变量使用(罕见)
如果你使用new,alloc或copy方法获得一个对象,则不需要执行任何其他操作,他将一直存在,你只要在拥有该对象的dealloc方法中释放该对象就可
- (void) doStuff
// flonkArray is an instance variable
flonkArray = [NSMutableArray new]; // count: 1
} // doStuff
- (void) dealloc
[flonkArray release]; // count: 0
[super dealloc];
} // dealloc
32、Cocoa程序才开始处理事件之前创建一个自动释放池,并在事件处理结束后销毁该自动释放池
33、保证内存占用比较小的一种方法,分段处理
for (i = 0; i & 1000000; i++) {
id object = [someArray objectAtIndex: i];
NSString *desc = [object description];
// and do something with the description
节省内存的方法:
NSAutoreleasePool *
pool = [[NSAutoreleasePool alloc] init];
for (i = 0; i & 1000000; i++) {
id object = [someArray objectAtIndex: i];
NSString *desc = [object descrption];
// and do something with the description
if (i % 1000 == 0) {
[pool release];
pool = [[NSAutoreleasePool alloc] init];
[pool release]
//自动释放池以栈的形式存在
34、Objective-C 2.0的垃圾回收机制,是一个可选择启用的功能,项目信息属性转到Build选项卡,在Objective-C Garbage Collection选项选成Required [-fobjc-gc- only]即可
但注意:iPhone里面不能用
七:对象的初始化
35、两种方法
[类名 new]
//不熟悉Cocoa的开发人员使用的辅助方法
[[类名 alloc] init]
//主要使用方法
36、分配(allocation)
向某个发送
内存区域 :全部初始化为0
float : 0.0
指针 : nil
37、两种格式
Car *car = [[Car alloc] init];
//推荐使用,这种嵌套调用非常重要,因为初始化方法返回的对象可能与分配的对象不同,虽然很奇怪,但是它的确会发生
Car *car = [Car alloc];
[car init]; //不推荐使用
38、编写init方法
- (id) init
if (self = [super init]) {
engine = [Engine new];
tires[0] = [Tire new];
tires[1] = [Tire new];
tires[2] = [Tire new];
tires[3] = [Tire new];
return (self);
//注意首行的self = [super init],从根类NSObject继承的类调用超类的初始化方法,可以使NSObject执行所需的任何操作,以便对象能够响应消息并处理保留计数器,而从其他类继承的类调用超类的初始化方法,可以使子类有机会实现自己全新的初始化
//实例变量所在的位置到隐藏的self参数的距离是固定的,如果从init方法返回一个新对象,则需要更新self,以便其后的任何实例变量的引用可以被映射到正确的位置,这也是self = [super init]使用的原因,记住,这个赋值操作只影响init方法中self的值,而不影响该范围以外的任何内容
// if (self = [super init])使用的原因,如果[super init]返回的结果是nil,则主体不会执行,只是赋值和检测非零值结合的方法,沿袭自C风格
39、便利初始化函数
//也可以自己构建
- (id) initWithFormat: (NSString *) format, ...;
- (id) initWithContentsOfFile: (NSString *)
//打开指定路径上的文件,读取文件内容,并使用文件类内容初始化一个字符串
使用方法:
string = [[NSString alloc]
initWithFormat: @"%d or %d", 25, 624];
string = [[NSString alloc]
initWithContentsOfFile: @"/tmp/words.txt"];
构造便利初始化函数
在@interface Tire: NSObject中添加方法声明
- (id) initWithPressure : (float) pressure
treadDepth: (float) treadD
在@implementation Tire中实现该方法
- (id) initWithPressure: (float) p
treadDepth: (float) td
if (self = [super init]) {
pressure =
treadDepth =
return (self);
} // initWithPressure:treadDepth:
这样就完成了初始化函数的定义,分配,初始化一体完成
tire = [[Tire alloc]
initWithPressure: 23 + i
treadDepth: 33 - i];
39、如果用NSMutableArray代替C数组,则就不用执行边界检查
40、指定初始化函数
有的时候定义了太多的初始化函数时,会出现一些细微的问题
例如下面的程序
@interface Tire : NSObject
float treadD
- (id) initWithPressure: (float)
- (id) initWithTreadDepth: (float) treadD //新增加的两个初始化函数
- (id) initWithPressure: (float) pressure
treadDepth: (float) treadD
- (void) setPressure: (float)
- (void) setTreadDepth: (float) treadD
- (float) treadD
@end // Tire
//声明了三个初始化函数
//新声明的初始化函数的实现
- (id) initWithPressure: (float) p
if (self = [super init]) {
pressure =
treadDepth = 20.0;
return (self);
} // initWithPressure
- (id) initWithTreadDepth: (float) td
if (self = [super init]) {
pressure = 34.0;
treadDepth =
return (self);
} // initWithTreadDepth
子类化问题:
@interface AllWeatherRadial : Tire
float rainH
float snowH
- (void) setRainHanding: (float) rainH
- (float) rainH
- (void) setSnowHandling: (float) snowH
- (float) snowH
@end // AllWeatherRadial
//枯燥的存取函数
- (void) setRainHandling: (float) rh
rainHandling =
} // setRainHandling
- (float) rainHandling
return (rainHandling);
} // rainHandling
- (void) setSnowHandling: (float) sh
snowHandling =
} // setSnowHandling
- (float) snowHandling
return (snowHandling);
} // snowHandling
- (NSString *) description
NSString *
desc = [[NSString alloc] initWithFormat:
@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",
[self pressure], [self treadDepth],
[self rainHandling],
[self snowHandling]];
return (desc);
} // description
//main.m函数中实现
for (i = 0; i & 4; i++) {
AllWeatherRadial *
tire = [[AllWeatherRadial alloc] init];
[car setTire: tire
atIndex: i];
[tire release];
运行的结果是下面这个样子的
AllWeatherRadial: 34.0 / 20.0 / 0.0 / 0.0
AllWeatherRadial: 34.0 / 20.0 / 0.0 / 0.0
AllWeatherRadial: 34.0 / 20.0 / 0.0 / 0.0
AllWeatherRadial: 34.0 / 20.0 / 0.0 / 0.0
I am a slant- 6. VROOOM!
//注:默认情况下初始化函数只会按最容易实现的方式去运行,这不是我要的结果,并且是错误的结果
解决办法:指定初始化函数(designated initializer)
- (id) init
if (self = [self initWithPressure: 34
treadDepth: 20]) {
return (self);
- (id) initWithPressure: (float) p
if (self = [self initWithPressure: p
treadDepth: 20.0]) {
return (self);
} // initWithPressure
- (id) initWithTreadDepth: (float) td
if (self = [self initWithPressure: 34.0
treadDepth: td]) {
return (self);
} // initWithTreadDepth
添加到AllWeatherRadial类的初始化函数
- (id) initWithPressure: (float) p
treadDepth: (float) td
if (self = [super initWithPressure: p
treadDepth: td]) {
rainHandling = 23.7;
snowHandling = 42.5;
return (self);
} // initWithPressure:treadDepth
此时我们再运行可以得到这样的结果
AllWeatherRadial: 34.0 / 20.0 / 23.7 / 42.5
AllWeatherRadial: 34.0 / 20.0 / 23.7 / 42.5
AllWeatherRadial: 34.0 / 20.0 / 23.7 / 42.5
AllWeatherRadial: 34.0 / 20.0 / 23.7 / 42.5
I am a slant- 6. VROOOM!
41、属性(property)是Objective-C 2.0中引入的,为了方便的编写存取方法
42、属性的使用方法
1)声明方法的简化
//旧的表示方法
#import &Foundation/Foundation.h&
#import "Tire.h"
@interface AllWeatherRadial : Tire {
float rainH
float snowH
- (void) setRainHandling: (float) rainH
- (float) rainH
- (void) setSnowHandling: (float) snowH
- (float) snowH
@end // AllWeatherRadial
//用属性表示后
#import &Foundation/Foundation.h&
#import "Tire.h"
@interface AllWeatherRadial : Tire {
float rainH
float snowH
@property float rainH
//表明该类有一个名为rainHanding的float型属性,你可以通过-setRainHanding: 来设置属性,通过-rainHanding来访问属性
@property float snowH
@end // AllWeatherRadial
//@property预编译命令的作用是自动声明属性的setter和getter方法
//属性的名称不必与实例变量名称相同,但是一般都是相同的
2)实现方法的简化
//百年老字号
#import "AllWeatherRadial.h"
@implementation AllWeatherRadial
- (id) initWithPressure: (float) p
treadDepth: (float) td
if (self = [super initWithPressure: p treadDepth: td]) {
rainHandling = 23.7;
snowHandling = 42.5;
return (self);
} // initWithPressure:treadDepth
- (void) setRainHandling: (float) rh
rainHandling =
} // setRainHandling
- (float) rainHandling
return (rainHandling);
} // rainHandling
- (void) setSnowHandling: (float) sh
snowHandling =
} // setSnowHandling
- (float) snowHandling
return (snowHandling);
} // snowHandling
- (NSString *) description
NSString *
desc = [[NSString alloc] initWithFormat:
@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",
[self pressure], [self treadDepth],
[self rainHandling],
[self snowHandling]];
return (desc);
} // description
@end // AllWeatherRadial
//改进后的方法
#import "AllWeatherRadial.h"
@implementation AllWeatherRadial
@synthesize rainH
@synthesize snowH
- (id) initWithPressure: (float) p treadDepth: (float) td
if (self = [super initWithPressure: p
treadDepth: td]) {
rainHandling = 23.7;
snowHandling = 42.5;
return (self);
} // initWithPressure:treadDepth
- (NSString *) description
NSString *
desc = [[NSString alloc] initWithFormat:
@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",
[self pressure], [self treadDepth],
[self rainHandling],
[self snowHandling]];
return (desc);
} // description
@end // AllWeatherRadial
//@synthesize也是一种新的编译器功能,表示&创建该属性的访问器&
//当遇到@synthesize rainH时,编译器将输出-setRainHanding:和- rainHanding方法的已编译代码
43、点表达式
点表达式(.),若出现在等号(=)左边,该属性名称的setter方法将被调动,多出现在对象变量右边,则该属性名册和那个的getter方法将被调用
//注:特性的点表达式和流行的键/值编码的后台工作没有联系
44、特性扩展
特性同样适用于int、char、BOOL和struct类型
(所有者对象保留被拥有的对象,而不是被拥有的对象保留所有者对象)
//可以使用一些声明,用于内存处理(那个是用垃圾回收机制的路过)
@property (copy) NSString *
@property (retain) Engine *
45、特性名和实例变量名字不相同的情况
@interface Car : NSObject {
NSString *
NSMutableArray *
@property (copy) NSString *
@property (retain) Engine *
//然后,修改@synthesize指令
@synthesize name =
编译器扔将创建-setName:和- name方法,但是在实现中却是用实例变量application
//这样做会有错误,因为我们直接访问的实例变量name已经被修改了,我们既可以选择搜索替换name,也可以将直接的实例变量访问修改为使用访问器访问,在init方法中,将
name = @&Car&;
self.name = @&Car& ;
//[self setName : @&Car&];
在dealloc中,使用一种高明的技巧:
self.name =
//使用nil参数调用setName:方法
生成的访问器将自动释放以前的name对象,并使用nil替代name
最后修改-description方法需要使用第一次被修改的NSLog()函数:
NSLog(@&%@ has:& , self.name);
46、只读特性
//默认的特性是支持可写可读的,原型如下
@property (readwrite, copy) NSString *
@property (readwrite, retain) Engine *
//但为了简便,为了消除重复
//只读属性的设置
@interface Me : NSObject {
float shoeS
NSString *licenseN
@property (readonly) float shoeS
@property (readonly) NSString *licenseN
//这类编译器只会生成getter方法,不会有setter方法
47、特性的局限性
//不支持那么需要接受额外参数的方法
- (void) setTire: (Tire *) tire
atIndex: (int)
- (Tire *) tireAtIndex: (int)
//这样的只能使用百年老字号
48、可以利用Objective-C的动态运行时分配机制,为现有的类添加新方法---这就叫类别(category)
//特别是那些不能创建之类的类,很是cool
49、创建类别
//如果你希望想一个array或者dictionary里面添加一个个数字,你需要一个个的封装,如果多,你会疯掉,可以为string类添加一个类别来完成这项工作
1)声明对象 //与类的声明格式类似
@interface NSString (NumberConvenience)
- (NSNumber *) lengthAsN
@end // NumberConvenience
//我们正在向String类里面添加一个NumberConvenience方法,可以添加很多个,只要名称不相同
2)实现部分
@implementation NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber
unsigned int length = [self length];
//获得字符串的长度
return ([NSNumber numberWithUnsignedInt: length]);
} // lengthAsNumber
@end // NumberConvenience
现在就可以用了
int main (int argc, const char *argv[])
NSAutoreleasePool *
pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *
dict = [NSMutableDictionary dictionary];
[dict setObject: [@"hello" lengthAsNumber]
forKey: @"hello"];
[dict setObject: [@"iLikeFish" lengthAsNumber]
forKey: @"iLikeFish"];
[dict setObject: [@"Once upon a time" lengthAsNumber]
forKey: @"Once upon a time"];
NSLog (@"%@", dict);
[pool release];
return (0);
//任何NSString类都将响应lengthAsNumber消息,正式这种兼容性使类别称为一个非常伟大的概念,不需要创建NSString的之类,类别同样可以完成同样的工作
50、类别的局限性
第一:无法向类别里面添加新的实例变量,类别里面没有位置容纳实例变量//也可以是用dictionary封装,但是不划算
第二:若名称冲突,类别的优先级更高(一般都是加一个前缀避免名称冲突)
51、类别的作用
Cocoa中类别主要用于3个目的
1)将类的实现分散到多个不同的文件或不同构架中
用类别分离文件时注意类别的写法,一个类的类别才能实现这个类的方法
2)创建对私有方法的前向引用
有些声明不需要写在.h文件中,因为有的时候这个只是本类的一个小的实现,声明太麻烦,而且让code reader比较难理解,就可以在.m中用类别声明一下
@interface Car (PrivateMethods)
- (void) moveTireFromPosition: (int) pos1
toPosition: (int) pos2;
@end //private Methods
3)向对象添加非正式协议
非正式协议表示这里有一些你可能希望实现的方法,因此你可以使用它们更好的完成工作
52、将类的实现分散到多个不同的文件或不同架构中
看文档中的NSWindows类
@interface NSWindow : NSResponder
然后是一大堆类别:
@interface NSWindow(NSKeyboardUI)
@interface NSWindow(NSToolbarSupport)
@interface NSWindow(NSDrag)
@interface NSWindow(NSCarbonExtensions)
@interface NSObject(NSWindowDelegate)
这样就就可以把一个大的文件分开使用,看起来方便,实用
53、run循环
[[NSRunLoop currentRunLoop] run];
是一种cocoa构造,它一直处于阻塞状态(即不执行任何处理),知道某些有趣的事情发生为止
//这个run方法将一直运行而不会返回,后面的代码将一直不执行
54、委托和类别
委托强调类别的另一种应用:被发送给委托对象的方法可以声明为一个NSObject的类别。NSNetService委托方法的声明如下
@interface NSObject
(NSNetServiceBrowserDelegateMethods)
- (void) netServiceBrowser: (NSNetServiceBrowser *) browser
didFindService: (NSNetService *) service
moreComing: (BOOL) moreC
- (void) netServiceBrowser: (NSNetServiceBrowser *) browser
didRemoveService: (NSNetService *) service
moreComing: (BOOL) moreC
通过这些方法声明为NSObject的类型,NSNetServiceBrowser的实现可以将这些消息之一发送个任何对象,无论这些对象实际上属于哪个类。这意味着,只要实现了委托方法,任何类的对象都可以成为委托对象
通过这种方法可以不继承(c++)和不实现某个特定的接口(java),就可以作为委托对象使用
55、NSObject提供了一个名为respondsToSelector:的方法,该方法访问对象以确定其是否能够响应某个特定的消息
56、复制的种类有Shallow Copy和deep copy
Shallow Copy不复制引用对象,新复制的对象只指向指向现有的引用对象
deep copy将复制所有的引用对象
57,[self class]妙用
Car *carCopy = [[[self class] allocWithZone: zone] init];
可以通过self的类型来判断运行结果,子类的用这个函数就是子类的结果
58,NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow: -(24 * 60 * 60)];
获取一个时间段以前的一个时间,dateWithTimeIntervalSinceNow 接受一个NSTimeInterval参数,是一个双精度值,以秒为单位
59.NSData 和 char*的转化
const char *string = "Hi there, this is a C string!";
NSData *data = [NSData dataWithBytes: string
length: strlen(string) + 1];
NSLog (@"data is %@", data);
//输出为ascll码
NSLog (@"%d byte string is '%s'", [data length], [data bytes]);
//格式化输出要的内容
60,有些属性文件(特别是首选项文件)是以二进制格式存储的,通过使用plutil命令:plutil -convert xml1 filename.plist可以转化成人们可读的形式
61,[phrase writeToFile: @"/tmp/verbiage.txt"
atomically: YES];的atomically 是用于通知cocoa是否应该首先将文件内容保存在临时文件中,当文件保存成功后,再将该临时文件和原始文件交换
62,编码对象
#import &Foundation/Foundation.h&
@interface Thingie : NSObject &NSCoding& {
NSString *
int magicN
float shoeS
NSMutableArray *subT
@property (copy) NSString *
@property int magicN
@property float shoeS
@property (retain) NSMutableArray *subT
- (id)initWithName: (NSString *) n
magicNumber: (int) mn
shoeSize: (float)
@end // Thingie
@implementation Thingie
@synthesize magicN
@synthesize shoeS
@synthesize subT
- (id)initWithName: (NSString *) n
magicNumber: (int) mn
shoeSize: (float) ss {
if (self = [super init]) {
self.name =
self.magicNumber =
self.shoeSize =
self.subThingies = [NSMutableArray array];
return (self);
- (void) dealloc {
[name release];
[subThingies release];
[super dealloc];
} // dealloc
- (NSString *) description {
NSString *description =
[NSString stringWithFormat: @"%@: %d/%.1f %@",
name, magicNumber, shoeSize, subThingies];
return (description);
} // description
- (void) encodeWithCoder: (NSCoder *) coder {
[coder encodeObject: name
forKey: @"name"];
[coder encodeInt: magicNumber
forKey: @"magicNumber"];
[coder encodeFloat: shoeSize
forKey: @"shoeSize"];
[coder encodeObject: subThingies
forKey: @"subThingies"];
} // encodeWithCoder
- (id) initWithCoder: (NSCoder *) decoder {
if (self = [super init]) {
self.name = [decoder decodeObjectForKey: @"name"];
self.magicNumber = [decoder decodeIntForKey: @"magicNumber"];
self.shoeSize = [decoder decodeFloatForKey: @"shoeSize"];
self.subThingies = [decoder decodeObjectForKey: @"subThingies"];
return (self);
} // initWithCoder
@end // Thingie
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Thingie *thing1;
thing1 = [[Thingie alloc]
initWithName: @"thing1"
magicNumber: 42
shoeSize: 10.5];
NSLog (@"some thing: %@", thing1);
// 使用NSData的两个子类NSKeyedArchiver和NSKeyedUnarchiver
NSData *freezeD
freezeDried = [NSKeyedArchiver archivedDataWithRootObject: thing1];
[thing1 release];
thing1 = [NSKeyedUnarchiver unarchiveObjectWithData: freezeDried];
NSLog (@"reconstituted thing: %@", thing1);
Thingie *anotherT
anotherThing =
[[[Thingie alloc]
initWithName: @"thing2"
magicNumber: 23
shoeSize: 13.0] autorelease];
[thing1.subThingies addObject: anotherThing];
anotherThing =
[[[Thingie alloc]
initWithName: @"thing3"
magicNumber: 17
shoeSize: 9.0] autorelease];
[thing1.subThingies addObject: anotherThing];
NSLog (@"thing with things: %@", thing1);
freezeDried = [NSKeyedArchiver archivedDataWithRootObject: thing1];
thing1 = [NSKeyedUnarchiver unarchiveObjectWithData: freezeDried];
NSLog (@"reconstituted multithing: %@", thing1);
[thing1.subThingies addObject: thing1];
// You really don't want to do this...
// NSLog (@"infinite thinging: %@", thing1);
freezeDried = [NSKeyedArchiver archivedDataWithRootObject: thing1];
[freezeDried writeToFile:@"/tmp/xiaoyuan" atomically:YES];
thing1 = [NSKeyedUnarchiver unarchiveObjectWithData: freezeDried];
[pool release];
return (0);
63,KVC(Key Value Code)
Advantage one:
NSLog (@"horsepower is %@", [engine valueForKey: @"horsepower"]); //这个会自动打包成NSNumber或NSValue
[engine setValue: [NSNumber numberWithInt: 150] //这个使用的时候要自己打包
forKey: @"horsepower"];
NSLog (@"horsepower is %@", [engine valueForKey: @"horsepower"]);
[car setValue: [NSNumber numberWithInt: 155]
forKeyPath: @"engine.horsepower"];//路径的获得
NSLog (@"horsepower is %@", [car valueForKeyPath: @"engine.horsepower"]);
NSArray *pressures = [car valueForKeyPath: @"tires.pressure"];//要是路径是一个数组就只能获取一个数组,不能只获取一个
NSLog (@"pressures %@", pressures);
Advantage two
NSNumber *
count = [garage valueForKeyPath: @"cars.@count"];
NSLog (@"We have %@ cars", count);
NSNumber *
sum = [garage valueForKeyPath: @"cars.@sum.mileage"];
NSLog (@"We have a grand total of %@ miles", sum);
NSNumber *avgM
avgMileage = [garage valueForKeyPath: @"cars.@avg.mileage"];
NSLog (@"average is %.2f", [avgMileage floatValue]);
NSNumber *min, *
min = [garage valueForKeyPath: @"cars.@min.mileage"];
max = [garage valueForKeyPath: @"cars.@max.mileage"];
NSLog (@"minimax: %@ / %@", min, max);
manufacturers = [garage valueForKeyPath: @"cars.@distinctUnionOfObjects.make"];
NSLog (@"makers: %@", manufacturers);
//另外,union 运算符指一组对象的并集
//distinct用于删除重复的内容
//遗憾的一点就是不能添加自的运算符
Advantage three
car = [[garage valueForKeyPath: @"cars"] lastObject];
NSArray *keys = [NSArray arrayWithObjects: @"make", @"model", @"modelYear", nil];
NSDictionary *carValues = [car dictionaryWithValuesForKeys: keys];
NSLog (@"Car values : %@", carValues);
NSDictionary *newValues =
[NSDictionary dictionaryWithObjectsAndKeys:
@"Chevy", @"make",
@"Nova", @"model",
[NSNumber numberWithInt:1964], @"modelYear",
[NSNull null], @"mileage",
[car setValuesForKeysWithDictionary: newValues];
NSLog (@"car with new values is %@", car);
//新装配过的car
KVC的一些特殊情况处理
case one: nil的处理
[car setValue:nil forKey: @"mileage"];
NSLog (@"Nil miles are %@", car.mileage);
这里的标量值mileage中的nil表示的是什么0?-1?pi?cocoa无法知道,可以再car类里面重写
- (void) setNilValueForKey: (NSString *) key {
if ([key isEqualToString: @"mileage"]) {
mileage = 0;
[super setNilValueForKey: key];
} // setNilValueForKey
case two:未定义的健的处理
在控制类里面写
- (void) setValue: (id) value
forUndefinedKey: (NSString *) key {
if (stuff == nil) {
stuff = [[NSMutableDictionary alloc] init];
[stuff setValue: value forKey: key];
} // setValueForUndefinedKey
- (id) valueForUndefinedKey:(NSString *)key {
id value = [stuff valueForKey: key];
return (value);
} // valueForUndefinedKey
64、Cocoa中提供NSPredicate的类,它用于指定过滤的条件
Cocoa用NSPredicate描述查询的方式,原理类似于在数据库中进行查询
计算谓词:
//基本的查询
NSPredicate *
predicate = [NSPredicate predicateWithFormat: @"name == 'Herbie'"];
BOOL match = [predicate evaluateWithObject: car];
NSLog (@"%s", (match) ? "YES" : "NO");
//在整个cars里面循环比较
predicate = [NSPredicate predicateWithFormat: @"engine.horsepower & 150"];
NSArray *cars = [garage cars];
for (Car *car in [garage cars]) {
if ([predicate evaluateWithObject: car]) {
NSLog (@"%@", car.name);
//输出完整的信息
predicate = [NSPredicate predicateWithFormat: @"engine.horsepower & 150"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
//含有变量的谓词
NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@"name == $NAME"];
NSDictionary *varD
varDict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Herbie", @"NAME", nil];
predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];
NSLog(@"SNORGLE: %@", predicate);
match = [predicate evaluateWithObject: car];
NSLog (@"%s", (match) ? "YES" : "NO");
//注意不能使用$VARIABLE作为路径名,因为它值代表值
//谓词字符窜还支持c语言中一些常用的运算符
*&=和=&: 大于或等于
*&=和=&: 小于或等于
*!=和&&: 不等于
*括号运算符,AND,OR,NOT,&&,||,! (可以不区分大小写,但建议一致)
predicate = [NSPredicate predicateWithFormat: @"(engine.horsepower & 50) AND (engine.horsepower & 200)"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"oop %@", results);
predicate = [NSPredicate predicateWithFormat: @"name & 'Newton'"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", [results valueForKey: @"name"]);
//强大的数组运算符
predicate = [NSPredicate predicateWithFormat:
@"engine.horsepower BETWEEN { 50, 200 }"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
NSArray *betweens = [NSArray arrayWithObjects:
[NSNumber numberWithInt: 50], [NSNumber numberWithInt: 200], nil];
predicate = [NSPredicate predicateWithFormat: @"engine.horsepower BETWEEN %@", betweens];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
predicateTemplate = [NSPredicate predicateWithFormat: @"engine.horsepower BETWEEN $POWERS"];
varDict = [NSDictionary dictionaryWithObjectsAndKeys: betweens, @"POWERS", nil];
predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
//IN运算符
predicate = [NSPredicate predicateWithFormat: @"name IN { 'Herbie', 'Snugs', 'Badger', 'Flap' }"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", [results valueForKey: @"name"]);
predicate = [NSPredicate predicateWithFormat: @"SELF.name IN { 'Herbie', 'Snugs', 'Badger', 'Flap' }"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", [results valueForKey: @"name"]);
names = [cars valueForKey: @"name"];
predicate = [NSPredicate predicateWithFormat: @"SELF IN { 'Herbie', 'Snugs', 'Badger', 'Flap' }"];
results = [names filteredArrayUsingPredicate: predicate];//这里限制了SELF的范围
NSLog (@"%@", results);
//BEGINSWITH,ENDSWITH,CONTAINS
//附加符号,[c],[d],[cd],c表示不区分大小写,d表示不区分发音字符,cd表示什么都不区分
predicate = [NSPredicate predicateWithFormat: @"name BEGINSWITH 'Bad'"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
predicate = [NSPredicate predicateWithFormat: @"name BEGINSWITH 'HERB'"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
predicate = [NSPredicate predicateWithFormat: @"name BEGINSWITH[cd] 'HERB'"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
//LIKE运算符(通配符)
predicate = [NSPredicate predicateWithFormat: @"name LIKE[cd] '*er*'"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
predicate = [NSPredicate predicateWithFormat: @"name LIKE[cd] '???er*'"];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@"%@", results);
一:Objective-C入门1、Cocoa的组成苹果公司将Cocoa、Carbon、QuickTime和OpenGL等技术作为框架集提供Cocoa组成部分有:Foundation框架(有很多有用的,面向数据的低级类和数据结构)Application Kit(也称AppKit)框架(包含了所有的用户接口对象和高级类,例如NS&&),还有一个支持框架的套件,包括Core Animation和Core Image。2、NSLog相当于printf()NSLog(@"hello Objective-C");//注:@是Objective-C在标准C语言基础上添加的特征之一,双引号的字符串前面有一个@,这表示引用的字符串应该作为Cocoa的NSString元素处理NSLog(@"are %d and %d different? %@",5,5,boolString(areTheyDifferent));//注意%@:使用NSLog输出任何对象值时,都会使用这个格式说明3、BOOL使用8位存储,YES定义为1,NO定义为0,大于1不为YES,跟标准C不同。若不小心将一个长于1字节的整型值赋给BOOL,则只截取低八位Obejective-C中1不等于1,绝对不要将BOOL值和YES比较二:面向对象的Objective-C4、使用间接从本地读取文件的例子#import &Foundation/Foundation.h&int main(int argc,const char * argv[]) {&&& if(argc == 1){&&&&&&& NSLog(@"you need to provide a file name");&&&&&&& return (1);&&& }&&& FILE *wordFile = fopen(argv[1] , "r");&&& char word[100];&&& while (fgets(word,100,wordFile)){ &&& //fget调用会保留分开每一行的换行符,我们不需要,把它替换为0,表示字符串的结束&&& word[strlen(word)-1] ='\0';&&& NSLog(@"%s is %d characters long",word,strlen(word));}//运行用 ./Word-Length-4 /tmp/words.txt若给了文件路径,那么argc会大于1,然后我们可以查询argv数组得到文件路径。argv[1]保存着用户提供的文件名,argv[0]保存着程序名。在XCode中编译此程序需要在XCode文件列表中展开Executables,双击程序名,在Arguments区域中添加启动参数5、idid是一种泛型,用于表示任何类的对象,id实际上是一个指针,指向其中的某个结构6、[]例[shape draw]第一项是对象名,其余部分是要执行的操作7、Objective-C的OOP范例1)@interface部分(一般都作为.h单独书写,声明部分)@interface Circle:NSObject& //说明这是为Circle的新类定义的接口{&&& ShapeColor fillC&&& ShapeR}& //括号内的是Circle对象需要的各种数据成员- (void) setFilColor:(ShapeColor) fillC&& //先行短线表明&这是新方法的声明&如果是&+&则表示是类方法,也称工厂方法- (void) setBounds:(ShapeRect)- (void)@end& //Circle2)@implementation部分(一般写为.m文件,实现部分)@implementation Circle& //@implementation是一个编译器指令,表明你将为某个类提供代码- (void) setFillColor:(ShapeColor) c& //在这里如果继续使用参数名fillColor,就会隐藏fillColor实例变量,并且有警告//我们已经定义了一个名为fillColor的实例变量,可以在该方法中引用该变量,如果使用相同的另一个变量,那么前一个会屏蔽{&&& fillColor =}- (void) setBounds:(ShapeRect) b {&&& bounds =}- (void) draw{&&& NSLog("^^^")}@end //Circle可以在@implementation中定义那些在@interface中无相应声明的方法,可以把他们看做是石油方法,仅在类的实现中使用。注:Objective-C不存在真正的私有方法,从而禁止其他代码调用它。这是Objective-C动态本质的副作用。8、中缀符(infix natation)方法的名称和及其参数都是合在一起的例如一个参数:[citcle setFillColor : KRedColor];两个参数:[circle setStringValue : @&hello there& color : KBlueColor];9、继承(X是一个Y,isa)1)Objective-C不支持多继承,我们可以通过Objective-C的其他特性获取多继承的优点,例如分类和协议2)继承中方法的定义可以使用空正文和一个虚(dummy)值都是可以的3)方法调度当代码发送消息时,Objective-C的方法调度将在当前分类中搜索相应的方法,如果找不到,则在该对象的超类中进行查找4)实例变量10、复合(X有一个Y,has)严格的讲,只有对象间的组合才叫做复合,诸如int、float、enum和struct等基本类型都认为是对象的一部分11、init- (id) init{&&& if (self = [super init]) { //将[super init]得结果赋给self是Objective-C的标准惯例,为了防止超类的初始化过程中返回的对象不同于原先创建的对象&&& //若要超类要完成所需的一次性初始化,需要调用[super init],init方法返回的值描述了被初始化的对象&&& engine = [Engine new];&&& tires[0] = [Tire new];&&& tires[1] = [Tire new];&&& tires[2] = [Tire new];&&& tires[3] = [Tire new];}return (self);} // init12、存取方法(accessor method)setter和gettersetter方法根据他所要更改的属性的名称来命名,并加上setgetter方法根据其返回的属性的名称来命名,不要加get三:源文件组织13、@class * 和import *.h@class创建一个类前声明,告诉编译器:相信我,以后你会知道这个到底是什么,但是现在,你只需要知道这些继承一个类的时候不能用@class,因为他们不是通过指针指向其他类,所以继承一个类时要用import *.h四:Xcode的使用14、更改自动注释中的公司名终端中:defaults write com.apple.apple.Xcode PBXCustomTemplateMacroDefinitions'{&ORGANIZATIONNAME& = &iPhone_xiaoyuan.com&;}&没有任何输出结果15键盘符号1)Mac按键符号2)Microsoft键盘和Mac键盘的对照Alt-&徽标键-&Option16、Xcode技巧1)同步显示有时候两个窗口中显示的内容并不是同步的,只有分别单击了它们,才能同步更新内容2)首行缩进选自,右键-&Re-indent selectionAlt [ 和 Alt ]可以把选中的代码左移和右移3)代码自动完成Tab 键可以按频率最高的填充完成词Esc 可以弹出提示列表(E表示枚举,f代表函数,#代表@define,m表示方法,C表示类)Ctl+. 在各选项中切换Shift+Ctrl+. 反向循环control+/ 在占位符之间切换4)批量编辑快照:File-&Make Snapshot查看快照:File-&Snapshot一次改变文件中的相同字符:选定,Edit-&Edit all in Scope,更改的时候都会变重构:选定,Edit-&Refactor,弹出对话框,输入要改成的字符(选中Snapshot后可以看见改变)5)键盘代替鼠标■ control-F: Move forward, to the right (same as the right arrow).■ control-B: Move backwards, to the left (same as the left arrow).■ control-P: Move to the previous line (same as the up arrow).■ control-N: Move to the next line (same as the down arrow).■ control-A: Move to the beginning of a line (same as the as command- left arrow).■ control-E: Move to the end of a line (same as the as command- right arrow).■ control-T: Transpose (swap) the characters on either side of the cursor.■ control-D: Delete the character to the right of the cursor.■ control-K: Kill (delete) the rest of the line. This is handy if you want to redo the end of a line of code.■ control-L: Center the insertion point in the window. This is great if you&ve lost your text cursor or want to quickly scroll the window so the insertion point is front and center.6)任意搜索在菜单栏上面搜索7)快速打开#import后的文件选中,File-&Open Quickly,Xcode就会打开文件。若不选择,则会打开Open Quickly对话框8)打开文档Option+双击9)调试时看数据鼠标放在上面一会就可以看到五:Foundation Kit17、一些有用的数据结构 (结构体能减少过程中的开销)1)NSRange&& //用来表示相关事物的范围typedef struct _NSRange {&&& u&&&} NSR例如&Objective-C is a cool language&中,&cool&可以用location为17,length为4的范围来表示有3种方式可以创建新的NSRange第一种:直接给字段赋值NSRrange.location = 17;range.length = 4;第二种:应用C语言的聚合结构赋值机制NSRange range = { 17, 4 };第三种:使用Cocoa提供的快捷函数NSMakeRange():NSRange range = NSMakeRange(17,4);//使用NSMakeRange()的好处是可以在任何使用函数的地方使用他//例如 [anObject flarbulateWithRange: NSMakeRange (13, 15)];2)几何数据类型typedef struct _NSPoint {&&&&&&} NSPtypedef struct _NSSize {&&&&&&} NSStypedef struct _NSRect {&&& NSP&&& NSS} NSR//Cocoa也为我们提供了这些类型的快捷函数:NSMakePoint()、NSMakeSize()和NSMakeRect()18、字符串(NSString和NSMutableString)A:不可变的字符串(NSString)1) 创建不可变的字符串函数:+ (id) stringWithFormat: (NSString *) format, ...;使用方法:NSString *height = [NSString stringWithFormat:@"Your height is %d feet, %dinches", 5, 11];2)NSString类中的方法① 大小函数:- (unsigned int)使用方法:if ([height length] & 35) {NSLog (@"wow, you're really tall!");}② 比较函数1:- (BOOL) isEqualToString: (NSString *) aS使用方法:NSString *thing1 = @"hello 5";NSString *thing2;thing2 = [NSString stringWithFormat: @"hello %d", 5];if ([thing1 isEqualToString: thing2]) {&&& NSLog (@"They are the same!");} //应用这个函数,不能用&==&,&==&只能比较字符串的指针值函数2:- (NSComparisonResult) compare: (NSString *)其中typedef enum _NSComparisonResult {&&& NSOrderedAscending = -1,&&& NSOrderedSame,&&& NSOrderedDescending} NSComparisonR使用方法:[@"aardvark" compare: @"zygote"]&& return NSOrderedAscending:.[@"zoinks" compare: @"jinkies"]&&& return NSOrderedDescending. And,[@"fnord" compare: @"fnord"]&&&&&& return NSOrderedSame.不区分大小写的比较函数: - (NSComparisonResult) compare: (NSString *) string&&&&&&& options: (unsigned)options参数是一个位掩码,可以用位或运算符(|)来添加这些选项标记一些常用的标记有■ NSCaseInsensitiveSearch: 不区分大小写■ NSLiteralSearch: 进行完全比较,区分大小写■ NSNumericSearch:比较字符串的字符个数,而不是字符值,若没项,&100&会排在&99&前面(一定要加)使用方法:if ([thing1 compare: thing2 options: NSCaseInsensitiveSearch | NSNumericSearch]== NSOrderedSame) {&&& NSLog (@"They match!");}③ 包含字符串判断函数:- (BOOL) hasPrefix: (NSString *) aS& //判断开头- (BOOL) hasSuffix: (NSString *) aS& //判断结尾- (NSRange) rangeOfString: (NSString *) aS //看字符串中是否包含其他字符串使用方法:NSString *filename = @"draft- chapter.pages";if ([fileName hasPrefix: @"draft") {&&& // this is a draft}if ([fileName hasSuffix: @".mov") {&&& // this is a movie}NSRrange = [fileName rangeOfString: @"chapter"];//返回range.start为6,range.length为7,若传递的参数在接受字符串中没有找到,那么range.start则等于NSNotFoundB)可变字符串(NSMutableString)1)创建可变的字符串方式1:函数:+ (id) stringWithCapacity: (unsigned) //这个容量只是给NSMutableString的一个建议使用方法:NSMutableString *string = [NSMutableString stringWithCapacity: 42];方法2:继承NSString中的方法NSMutableString *string = [NSMutableString stringWithFormat: @"jo%dy", 2];2)NSMutableString中的方法函数:- (void) appendString: (NSString *) aS- (void) appendFormat: (NSString *) format, ...;- (void) deleteCharactersInRange: (NSRange) //配合rangeOfString:一起连用使用方法:NSMutableString *string = [NSMutableString stringWithCapacity: 50];[string appendString: @"Hello there"];[string appendFormat: @"human %d!",39];NSMutableString *friends = [NSMutableString stringWithCapacity: 50];[friends appendString: @"James BethLynn Jack Evan"];NSRange jackRjackRange = [friends rangeOfString: @"Jack"];jackRange.length++;&& // eat the space that follows[friends deleteCharactersInRange: jackRange];19、NSArray和NSMutableArrayA) NSArray(不可改变的数组,是一个Cocoa类,用来存储对象的有序列表)NSArray的两个限制首先:它只能存储Objective-C的对象,而不能存储C语言中的基本数据类型,如:int, float, enum, struct,或者是NSArray中的随机指针然后:不能存储nil1)创建方法通过类的方法arrayWithObjects:创建一个新的NSArray使用方法:NSArray *array = [NSArray arrayWithObjects:@"one", @"two", @"three",nil]; //array是以nil结尾的,这是nil不能存储的原因2)常用方法- (unsigned) //获取数组包含的对象个数- (id) objecAtIndex : (unsigned int) //获取特定索引处的对象- componentsSeparatedByString://切分NSArray- componentsJoinedByString://合并NSString使用方法:for (i = 0; i & [array count]; i++) {&&& NSLog (@"index %d has %@.",i, [array objectAtIndex: i]);}NSString *string = @"oop:ack:bork:greeble:ponies";NSArray *chunks = [string componentsSeparatedByString: @":"];string = [chunks componentsJoinedByString: @" :- ) "];B)NSMutableArray(可变数组)1)创建方法,通过类方法arrayWithCapacity创建+ (id) arrayWithCapacity: (unsigned) numI使用方法:NSMutableArray *array = [NSMutableArray arrayWithCapacity: 17];2)常用方法- (void) addObject: (id) anO- (void) removeObjectAtIndex: (unsigned)使用方法:for (i = 0; i & 4; i++) {&&& Tire *tire = [Tire new];&&& [array addObject: tire];}[array removeObjectAtIndex: 1]; //删除第二个C)遍历数组的三种方式:通过索引、使用NAEnumerator和快速枚举1)索引遍历& //只有在真的需要索引访问数组时才应使用-objectAtIndex,例如跳跃数组或者同时遍历多个数组时for (i = 0; i & [array count]; i++) {&&& NSLog (@"index %d has %@.",i, [array objectAtIndex: i]);}2)使用NSEnumerator& //Leopard中被快速枚举替代创建方法:通过函数 - (NSEnumerator *) objectE使用方法:NSEnumerator *enumerator = [array objectEnumerator];& //如果想从后往前浏览集合,还有一个方法reverseEnumerator可以使用创建后通过while循环,条件是nextObject( 方法原型 - (id) nextObject );循环遍历的程序为:NSEnumerator *enumerator = [array objectEnumerator];while(thingie = [enumerator nextObject ]) {&&& NSLog(@&i found %@& , thingie);}//注:对可变数组进行枚举操作时,不能通过添加和删除对象这类方式来改变数组容器,如果这样做了,枚举器会觉得困惑,为你将会得到未定义结果3)快速枚举在Leopard中才开始的,Tiger中不能用for (NSString *string in array ) {&&& NSLog(@&i found %@& , string);}21、破除NSArray限制的方法1)基本类型a):Cocoa提供了NSNumber类来包装基本类型+ (NSNumber *) numberWithChar: (char)+ (NSNumber *) numberWithInt: (int)+ (NSNumber *) numberWithFloat: (float)+ (NSNumber *) numberWithBool: (BOOL)使用方法:NSNumber *numner;number = [NSNumber numberWithInt: 42];[array addObject: number];[dictionary setObject : number foyKey : @&Bork&];只要将一些基本类型封装到NSNumber中,就可以通过下面的实例方法重新获得其值- (char) charV- (int) intV- (float) floatV- (BOOL) boolV- (NSString *) stringV //允许自动转换Objective-C不支持自动装箱,要自己动手b):NSNumber是NSValue的子类,NSValue可以包装任意值创建新的NSValue+ (NSValue *) valueWithBytes: (const void *) value&&&&&&&&&&&&&&&&& objCType: (const char *)使用方法:NSRect rect = NSMakeRect (1, 2, 30, 40);NSValue *value = [NSValue valueWithBytes: &rect&&&&& objCType: @encode(NSRect)];& //encode编译器指令可以接受数据类型的名称并为你生成合适的字符串[array addObject: value];可以使用getValue:来提取数值(注意是get方法,指针)- (void) getValue: (void *) //调用时,要传递的是要存储这个数值的变量的地址使用方法value = [array objectAtIndex: 0];[value getValue: &rect];Cocoa提供了常用的struct型数据转换成NSValue的便捷方法+ (NSValue *) valueWithPoint: (NSPoint)+ (NSValue *) valueWithSize: (NSSize)+ (NSValue *) valueWithRect: (NSRect)- (NSPoint) pointV- (NSSize) sizeV- (NSRect) rectV使用方法:value = [NSValue valueWithRect: rect];[array addObject: value];....NSRect anotherRect = [value rectValue];2)NSNullNSNull大概是Cocoa里最简单的类了,只有一个方法+ (NSNull *)可以这样添加到集合中[contact setObject: [NSNull null]forKey: @"home fax machine"];访问时:homefax = [contact objectForKey: @"home fax machine"];if (homefax == [NSNull null]) {// ... no fax machine. rats.}//[NSNull null]总是返回一样份数值,所以你可以使用&==&讲该值与其他值进行比较&&22、NSDictionary和NSMutableDictionaryA) NSDictionary字典是关键字和其定义的集合,也被成为散列表或关联数组,使用的是键查询的优化存储方式1)创建方法: 使用dictionaryWithObjectsAndKeys:来创建字典+ (id) dictionaryWithObjectsAndKeys: (id) firstObject, ...;使用方法:Tire *t1 = [Tire new];Tire *t2 = [Tire new];Tire *t3 = [Tire new];Tire *t4 = [Tire new];NSDictionary *tires = [NSDictionary dictionaryWithObjectsAndKeys:t1, @"front- left", t2, @"front- right",t3, @"back- left", t4, @"back- right", nil];2)常用方法- (id) objectForKey: (id) aK使用方法:Tire *tire = [tires objectForKey: @"back- right"];& //如果没有则会返回nil值B) NSMutableDictionary1)创建方法:可以向类NSMutableDictionary发送dictionary消息也可以使用函数+ (id) dictionaryWithCapacity: (unsigned int) numI2)常用方法可以使用setObject:forKey:方法给字典添加元素:- (void) setObject: (id) anObject forKey: (id) aK- (void) removeObjectForKey: (id) aK使用方法:NSMutableDictionary *tires = [NSMutableDictionary dictionary];[tires setObject: t1 forKey: @"front- left"];[tires setObject: t2 forKey: @"front- right"];[tires setObject: t3 forKey: @"back- left"];[tires setObject: t4 forKey: @"back- right"];//若已经存在,则会用新值替换原有的值[tires removeObjectForKey: @"back- left"];23、不要创建NSString、NSArray或NSDictionary的子类,因为在Cocoa中,许多类实际上是以类簇的方式实现的,即他们是一群隐藏在通用接口之下的与实现相关的类24、Foundation实例 //查找文件A)使用枚举遍历int main (int argc, const char *argv[]){&&& NSAutoreleasePool *&&& pool = [[NSAutoreleasePool alloc] init];&& //自动释放池&&& NSFileManager * //Cocoa中有很多类都是单实例构架,即只需要一个实例,你真的只需要一个文件管理器&&& manager = [NSFileManager defaultManager]; // defaultManager方法创建一个属于我们的NSFileManager对象&&& NSString *&&& home = [@"~" stringByExpandingTildeInPath]; // stringByExpandingTildeInPath方法可将~替换成当前用户的主目录&&& NSDirectoryEnumerator * //NSEnumerator的子类&&& direnum = [manager enumeratorAtPath: home]; //创建一个枚举条件&&& NSMutableArray *&&& files = [NSMutableArray arrayWithCapacity: 42]; //把搜索的结果作为文件存储&&& NSString *&&& while (filename = [direnum nextObject]) {//调用nextObject时,都会返回该目录中的一个文件的另一个路径,也可搜索子目录&&&&&&& if ([[filename pathExtension]& // pathExtension输出文件的扩展名(去掉了前面的点.)&&&&&&& isEqualTo: @"jpg"]) {&&&&&&&&&&& [files addObject: filename];&&&&&&& }&&& }&&& NSEnumerator *&&& fileenum = [files objectEnumerator];&&& while (filename = [fileenum nextObject]) {&&&&&&& NSLog (@"%@", filename);&&& }&&& [pool drain];&&& return (0);} // mainB)使用快速遍历int main (int argc, const char * argv[]) {&&& NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];&&& NSFileManager *&&& manager = [NSFileManager defaultManager];&&& NSString *&&& home = [@"~" stringByExpandingTildeInPath];&&& NSMutableArray *&&& files = [NSMutableArray arrayWithCapacity: 42];&&& for (NSString *filename&&& in [manager enumeratorAtPath: home]) {&&&&&&& if ([[filename pathExtension]&&&&&&& isEqualTo: @"jpg"]) {&&&&&&&&&&& [files addObject: filename];&&&&&&& }&&& }&&& for (NSString *filename in files) {&&&&&&& NSLog (@"%@", filename);&&& }}六:内存管理25、Cocoa采用引用计数(reference counting)的技术,有时称为保留计数。每个对象有一个与之相关联的整数,称做为他的引用计数器或保留计数器- (id) - (void)- (unsigned) retainC& //当前值26、对象所有权的处理- (void) setEngine: (Engine *) newEngine{[newEngine retain];[engine release];engine = newE} // setEngine原则:先保存新对象,再释放员对象27、自动释放程序会自动建立一个自动释放池(autorelease pool),他是一个存放实体的池(集合),这些实体可能是对象,能够被自动释放。自动释放池创建代码NSAutoreleasePool& *pool;pool = [[NSAutoreleasePool& alloc]& init];&&[pool& release];NSObject类提供了一个antorelease方法:- (id)//该方法预先定义了一条在将来某个时间发送的release消息,其返回值是接收消息的对象,retain采用了相同的技术,使嵌套调用更加容易。//当给一个对象发送autorelease消息时,实际上是将对象添加到NSAutoreleasePool方法中,当自动释放池销毁了,会像该池中的所有对象发送release消息例如- (NSString *) description{&&& NSString *&&& description = [[NSString alloc]&&&&& initWithFormat: @"I am %d years old", 4];&&& return ([description autorelease]); //因为descriptor方法首先创建了一个新的字符串对象,然后自动释放该对象,最后将其返回给NSLog()函数} // description29、Cocoa内存管理原则如果使用new,alloc或copy操作获得一个对象,则该对象的保留计数器值加1,release减1如果通过任何其他方法获得一个对象,则假设该对象的保留计数器值为1,而且已经被设置为自动释放如果保留了某个对象,则必须保持retain方法和release方法使用的次数相同30、NSColor的blueColor方法返回一个全局单例对象31、一直拥有对象希望在多个代码段中一直拥有某个对象常见的方法有:在其他对象中使用这些变量,将它们加入到诸如NSArray或NSDictionary等集合中,或将其作为全局变量使用(罕见)如果你使用new,alloc或copy方法获得一个对象,则不需要执行任何其他操作,他将一直存在,你只要在拥有该对象的dealloc方法中释放该对象就可- (void) doStuff{&&& // flonkArray is an instance variable&&& flonkArray = [NSMutableArray new]; // count: 1} // doStuff- (void) dealloc{&&& [flonkArray release]; // count: 0&&& [super dealloc];} // dealloc32、Cocoa程序才开始处理事件之前创建一个自动释放池,并在事件处理结束后销毁该自动释放池33、保证内存占用比较小的一种方法,分段处理for (i = 0; i & 1000000; i++) {id object = [someArray objectAtIndex: i];NSString *desc = [object description];// and do something with the description}节省内存的方法:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];for (i = 0; i & 1000000; i++) {id object = [someArray objectAtIndex: i];NSString *desc = [object descrption];// and do something with the descriptionif (i % 1000 == 0) {[pool release];pool = [[NSAutoreleasePool alloc] init];}}[pool release]//自动释放池以栈的形式存在34、Objective-C 2.0的垃圾回收机制,是一个可选择启用的功能,项目信息属性转到Build选项卡,在Objective-C Garbage Collection选项选成Required [-fobjc-gc- only]即可但注意:iPhone里面不能用七:对象的初始化35、两种方法[类名 new]& //不熟悉Cocoa的开发人员使用的辅助方法[[类名 alloc] init]&& //主要使用方法36、分配(allocation)向某个发送内存区域 :全部初始化为0BOOL :NOint : 0float : 0.0指针 : nil37、两种格式Car *car = [[Car alloc] init];& //推荐使用,这种嵌套调用非常重要,因为初始化方法返回的对象可能与分配的对象不同,虽然很奇怪,但是它的确会发生Car *car = [Car alloc];[car init]; //不推荐使用38、编写init方法- (id) init{&&& if (self = [super init]) {&&&&&&& engine = [Engine new];&&&&&&& tires[0] = [Tire new];&&&&&&& tires[1] = [Tire new];&&&&&&& tires[2] = [Tire new];&&&&&&& tires[3] = [Tire new];&&& }&&& return (self);} // init//注意首行的self = [super init],从根类NSObject继承的类调用超类的初始化方法,可以使NSObject执行所需的任何操作,以便对象能够响应消息并处理保留计数器,而从其他类继承的类调用超类的初始化方法,可以使子类有机会实现自己全新的初始化//实例变量所在的位置到隐藏的self参数的距离是固定的,如果从init方法返回一个新对象,则需要更新self,以便其后的任何实例变量的引用可以被映射到正确的位置,这也是self = [super init]使用的原因,记住,这个赋值操作只影响init方法中self的值,而不影响该范围以外的任何内容// if (self = [super init])使用的原因,如果[super init]返回的结果是nil,则主体不会执行,只是赋值和检测非零值结合的方法,沿袭自C风格39、便利初始化函数& //也可以自己构建- (id) initWithFormat: (NSString *) format, ...;- (id) initWithContentsOfFile: (NSString *)& //打开指定路径上的文件,读取文件内容,并使用文件类内容初始化一个字符串使用方法:string = [[NSString alloc]& initWithFormat: @"%d or %d", 25, 624];string = [[NSString alloc]& initWithContentsOfFile: @"/tmp/words.txt"]; 构造便利初始化函数例如在@interface Tire: NSObject中添加方法声明- (id) initWithPressure : (float) pressure&&&&&&&&&&&&&&&&& treadDepth: (float) treadD在@implementation Tire中实现该方法- (id) initWithPressure: (float) p&&&&&&&&&& treadDepth: (float) td{if (self = [super init]) {pressure =treadDepth =}return (self);} // initWithPressure:treadDepth:这样就完成了初始化函数的定义,分配,初始化一体完成Tire *tire = [[Tire alloc]initWithPressure: 23 + itreadDepth: 33 - i];39、如果用NSMutableArray代替C数组,则就不用执行边界检查40、指定初始化函数有的时候定义了太多的初始化函数时,会出现一些细微的问题例如下面的程序@interface Tire : NSObject{float treadD}- (id) initWithPressure: (float)- (id) initWithTreadDepth: (float) treadD //新增加的两个初始化函数- (id) initWithPressure: (float) pressuretreadDepth: (float) treadD- (void) setPressure: (float)- (float)- (void) setTreadDepth: (float) treadD- (float) treadD@end // Tire//声明了三个初始化函数//新声明的初始化函数的实现- (id) initWithPressure: (float) p{if (self = [super init]) {pressure =treadDepth = 20.0;}return (self);} // initWithPressure- (id) initWithTreadDepth: (float) td{if (self = [super init]) {pressure = 34.0;treadDepth =}return (self);} // initWithTreadDepth问题来了子类化问题:@interface AllWeatherRadial : Tire{&&& float rainH&&& float snowH}- (void) setRainHanding: (float) rainH- (float) rainH- (void) setSnowHandling: (float) snowH- (float) snowH@end // AllWeatherRadial//枯燥的存取函数- (void) setRainHandling: (float) rh{rainHandling =} // setRainHandling- (float) rainHandling{return (rainHandling);} // rainHandling- (void) setSnowHandling: (float) sh{snowHandling =} // setSnowHandling- (float) snowHandling{return (snowHandling);} // snowHandling- (NSString *) description{NSString *desc = [[NSString alloc] initWithFormat:@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",[self pressure], [self treadDepth],[self rain}

我要回帖

更多关于 圆的周长公式 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信