日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Objective-C入門教程

 sam225 2010-08-16
一:Objective-C入門

1、Cocoa的組成

蘋果公司將Cocoa、Carbon、QuickTime和OpenGL等技術(shù)作為框架集提供

Cocoa組成部分有:

Foundation框架(有很多有用的,面向數(shù)據(jù)的低級(jí)類和數(shù)據(jù)結(jié)構(gòu))

Application Kit(也稱AppKit)框架(包含了所有的用戶接口對(duì)象和高級(jí)類,例如NS……)

,還有一個(gè)支持框架的套件,包括Core Animation和Core Image。


2、NSLog相當(dāng)于printf()

NSLog(@"hello Objective-C");

//注:@是Objective-C在標(biāo)準(zhǔn)C語言基礎(chǔ)上添加的特征之一,雙引號(hào)的字符串前面有一個(gè)@,這表示引用的字符串應(yīng)該作為Cocoa的NSString元素處理



NSLog(@"are %d and %d different? %@",5,5,boolString(areTheyDifferent));

//注意%@:使用NSLog輸出任何對(duì)象值時(shí),都會(huì)使用這個(gè)格式說明


3、BOOL使用8位存儲(chǔ),YES定義為1,NO定義為0,大于1不為YES,跟標(biāo)準(zhǔn)C不同。

若不小心將一個(gè)長于1字節(jié)的整型值賦給BOOL,則只截取低八位

Obejective-C中1不等于1,絕對(duì)不要將BOOL值和YES比較



二:面向?qū)ο蟮腛bjective-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調(diào)用會(huì)保留分開每一行的換行符,我們不需要,把它替換為0,表示字符串的結(jié)束

word[strlen(word)-1] ='\0';

NSLog(@"%s is %d characters long",word,strlen(word));

}


//運(yùn)行用 ./Word-Length-4 /tmp/words.txt

若給了文件路徑,那么argc會(huì)大于1,然后我們可以查詢argv數(shù)組得到文件路徑。argv[1]保存著用戶提供的文件名,argv[0]保存著程序名。

在XCode中編譯此程序需要在XCode文件列表中展開Executables,雙擊程序名,在Arguments區(qū)域中添加啟動(dòng)參數(shù)



5、id

id是一種泛型,用于表示任何類的對(duì)象,id實(shí)際上是一個(gè)指針,指向其中的某個(gè)結(jié)構(gòu)


6、[]

例[shape draw]

第一項(xiàng)是對(duì)象名,其余部分是要執(zhí)行的操作


7、Objective-C的OOP范例

1)@interface部分(一般都作為.h單獨(dú)書寫,聲明部分)

@interface Circle:NSObject  //說明這是為Circle的新類定義的接口

{

ShapeColor fillColor;

ShapeRect bounds;

 //括號(hào)內(nèi)的是Circle對(duì)象需要的各種數(shù)據(jù)成員


- (void) setFilColor:(ShapeColor) fillColor;   //先行短線表明“這是新方法的聲明”如果是“+”則表示是類方法,也稱工廠方法


- (void) setBounds:(ShapeRect) bounds;


- (void) draw;


@end  //Circle


2)@implementation部分(一般寫為.m文件,實(shí)現(xiàn)部分)

@implementation Circle  //@implementation是一個(gè)編譯器指令,表明你將為某個(gè)類提供代碼


- (void) setFillColor:(ShapeColor) c  //在這里如果繼續(xù)使用參數(shù)名fillColor,就會(huì)隱藏fillColor實(shí)例變量,并且有警告

//我們已經(jīng)定義了一個(gè)名為fillColor的實(shí)例變量,可以在該方法中引用該變量,如果使用相同的另一個(gè)變量,那么前一個(gè)會(huì)屏蔽

{

fillColor = c;

}


- (void) setBounds:(ShapeRect) b  

{

bounds = b;

}


- (void) draw

{

NSLog("^^^")

}


@end //Circle

可以在@implementation中定義那些在@interface中無相應(yīng)聲明的方法,可以把他們看做是石油方法,僅在類的實(shí)現(xiàn)中使用。

注:Objective-C不存在真正的私有方法,從而禁止其他代碼調(diào)用它。這是Objective-C動(dòng)態(tài)本質(zhì)的副作用。


8、中綴符(infix natation)

方法的名稱和及其參數(shù)都是合在一起的

例如

一個(gè)參數(shù):

[citcle setFillColor : KRedColor];

兩個(gè)參數(shù):

[circle setStringValue : @”hello there” color : KBlueColor];


9、繼承(X是一個(gè)Y,isa)

1)Objective-C不支持多繼承,我們可以通過Objective-C的其他特性獲取多繼承的優(yōu)點(diǎn),例如分類和協(xié)議


2)繼承中方法的定義

可以使用空正文和一個(gè)虛(dummy)值都是可以的


3)方法調(diào)度

當(dāng)代碼發(fā)送消息時(shí),Objective-C的方法調(diào)度將在當(dāng)前分類中搜索相應(yīng)的方法,如果找不到,則在該對(duì)象的超類中進(jìn)行查找


4)實(shí)例變量



10、復(fù)合(X有一個(gè)Y,has)

嚴(yán)格的講,只有對(duì)象間的組合才叫做復(fù)合,諸如int、float、enum和struct等基本類型都認(rèn)為是對(duì)象的一部分
2010-2-13 18:58:52
11、init

- (id) init

{

if (self = [super init]) { //將[super init]得結(jié)果賦給self是Objective-C的標(biāo)準(zhǔn)慣例,為了防止超類的初始化過程中返回的對(duì)象不同于原先創(chuàng)建的對(duì)象

//若要超類要完成所需的一次性初始化,需要調(diào)用[super init],init方法返回的值描述了被初始化的對(duì)象

engine = [Engine new];

tires[0] = [Tire new];

tires[1] = [Tire new];

tires[2] = [Tire new];

tires[3] = [Tire new];

}

return (self);

} // init


12、存取方法(accessor method)

setter和getter

setter方法根據(jù)他所要更改的屬性的名稱來命名,并加上set

getter方法根據(jù)其返回的屬性的名稱來命名,不要加get





三:源文件組織

13、@class * 和import *.h

@class創(chuàng)建一個(gè)類前聲明,告訴編譯器:相信我,以后你會(huì)知道這個(gè)到底是什么,但是現(xiàn)在,你只需要知道這些

繼承一個(gè)類的時(shí)候不能用@class,因?yàn)樗麄儾皇峭ㄟ^指針指向其他類,所以繼承一個(gè)類時(shí)要用import *.h



四:Xcode的使用

14、更改自動(dòng)注釋中的公司名

終端中:

defaults write com.apple.apple.Xcode PBXCustomTemplateMacroDefinitions

‘{“ORGANIZATIONNAME” = “iPhone_xiaoyuan.com”;}’

沒有任何輸出結(jié)果


15鍵盤符號(hào)

1)Mac按鍵符號(hào)


2)Microsoft鍵盤和Mac鍵盤的對(duì)照

Alt->

徽標(biāo)鍵->Option


16、Xcode技巧

1)同步顯示

有時(shí)候兩個(gè)窗口中顯示的內(nèi)容并不是同步的,只有分別單擊了它們,才能同步更新內(nèi)容

2)首行縮進(jìn)

選自,右鍵->Re-indent selection

Alt [ 和 Alt ]可以把選中的代碼左移和右移

3)代碼自動(dòng)完成

Tab 鍵可以按頻率最高的填充完成詞

Esc 可以彈出提示列表(E表示枚舉,f代表函數(shù),#代表@define,m表示方法,C表示類)

Ctl+. 在各選項(xiàng)中切換

Shift+Ctrl+. 反向循環(huán)

control+/ 在占位符之間切換

4)批量編輯

快照:File->Make Snapshot

查看快照:File->Snapshot

一次改變文件中的相同字符:選定,Edit->Edit all in Scope,更改的時(shí)候都會(huì)變

重構(gòu):選定,Edit->Refactor,彈出對(duì)話框,輸入要改成的字符(選中Snapshot后可以看見改變)

5)鍵盤代替鼠標(biāo)

■ 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后的文件選中,F(xiàn)ile->Open Quickly,Xcode就會(huì)打開文件。若不選擇,則會(huì)打開Open Quickly對(duì)話框

8)打開文檔

Option+雙擊

9)調(diào)試時(shí)看數(shù)據(jù)

鼠標(biāo)放在上面一會(huì)就可以看到
2010-2-13 18:59:15
五:Foundation Kit

17、一些有用的數(shù)據(jù)結(jié)構(gòu) (結(jié)構(gòu)體能減少過程中的開銷)

1)NSRange   //用來表示相關(guān)事物的范圍

typedef struct _NSRange {

unsigned int location;

unsigned int length;

} NSRange;

例如“Objective-C is a cool language”中,“cool”可以用location為17,length為4的范圍來表示


有3種方式可以創(chuàng)建新的NSRange

第一種:直接給字段賦值

NSRange range;

range.location = 17;

range.length = 4;

第二種:應(yīng)用C語言的聚合結(jié)構(gòu)賦值機(jī)制

NSRange range = { 17, 4 };

第三種:使用Cocoa提供的快捷函數(shù)NSMakeRange():

NSRange range = NSMakeRange(17,4);

//使用NSMakeRange()的好處是可以在任何使用函數(shù)的地方使用他

//例如 [anObject flarbulateWithRange: NSMakeRange (13, 15)];


2)幾何數(shù)據(jù)類型

typedef struct _NSPoint {

float x;

float y;

} NSPoint;


typedef struct _NSSize {

float width;

float height;

} NSSize;


typedef struct _NSRect {

NSPoint origin;

NSSize size;

} NSRect;


//Cocoa也為我們提供了這些類型的快捷函數(shù):NSMakePoint()、NSMakeSize()和NSMakeRect()


18、字符串(NSString和NSMutableString)

A:不可變的字符串(NSString)

1) 創(chuàng)建不可變的字符串

函數(shù):+ (id) stringWithFormat: (NSString *) format, ...;

使用方法:

NSString *height;

height = [NSString stringWithFormat:@"Your height is %d feet, %dinches", 5, 11];



2)NSString類中的方法

① 大小

函數(shù):- (unsigned int) length;

使用方法:

if ([height length] > 35) {

NSLog (@"wow, you're really tall!");

}


② 比較

函數(shù)1:- (BOOL) isEqualToString: (NSString *) aString;

使用方法:

NSString *thing1 = @"hello 5";

NSString *thing2;

thing2 = [NSString stringWithFormat: @"hello %d", 5];

if ([thing1 isEqualToString: thing2]) {

NSLog (@"They are the same!");

} //應(yīng)用這個(gè)函數(shù),不能用“==”,“==”只能比較字符串的指針值


函數(shù)2:- (NSComparisonResult) compare: (NSString *) string;

其中

typedef enum _NSComparisonResult {

NSOrderedAscending = -1,

NSOrderedSame,

NSOrderedDescending

} NSComparisonResult;

使用方法:

[@"aardvark" compare: @"zygote"]   return NSOrderedAscending:.

[@"zoinks" compare: @"jinkies"]    return NSOrderedDescending. And,

[@"fnord" compare: @"fnord"]       return NSOrderedSame.


不區(qū)分大小寫的比較

函數(shù): - (NSComparisonResult) compare: (NSString *) string

        options: (unsigned) mask;

options參數(shù)是一個(gè)位掩碼,可以用位或運(yùn)算符(|)來添加這些選項(xiàng)標(biāo)記

一些常用的標(biāo)記有

■ NSCaseInsensitiveSearch: 不區(qū)分大小寫

■ NSLiteralSearch: 進(jìn)行完全比較,區(qū)分大小寫

■ NSNumericSearch:比較字符串的字符個(gè)數(shù),而不是字符值,若沒項(xiàng),“100”會(huì)排在“99”前面(一定要加)

使用方法:

if ([thing1 compare: thing2

options: NSCaseInsensitiveSearch|NSNumericSearch]== NSOrderedSame) {

NSLog (@"They match!");

}


③ 包含字符串判斷

函數(shù):

- (BOOL) hasPrefix: (NSString *) aString;  //判斷開頭

- (BOOL) hasSuffix: (NSString *) aString;  //判斷結(jié)尾

- (NSRange) rangeOfString: (NSString *) aString; //看字符串中是否包含其他字符串


使用方法:

NSString *filename = @"draft- chapter.pages";

if ([fileName hasPrefix: @"draft") {

// this is a draft

}

if ([fileName hasSuffix: @".mov") {

// this is a movie

}

NSRange range;

range = [fileName rangeOfString: @"chapter"];

//返回range.start為6,range.length為7,若傳遞的參數(shù)在接受字符串中沒有找到,那么range.start則等于NSNotFound


B)可變字符串(NSMutableString)

1)創(chuàng)建可變的字符串

方式1:

函數(shù):+ (id) stringWithCapacity: (unsigned) capacity; //這個(gè)容量只是給NSMutableString的一個(gè)建議

使用方法:

NSMutableString *string;

string = [NSMutableString stringWithCapacity: 42];

方法2:

繼承NSString中的方法

NSMutableString *string;

string = [NSMutableString stringWithFormat: @"jo%dy", 2];


2)NSMutableString中的方法

函數(shù):

- (void) appendString: (NSString *) aString;

- (void) appendFormat: (NSString *) format, ...;

- (void) deleteCharactersInRange: (NSRange) range; //配合rangeOfString:一起連用


使用方法:

NSMutableString *string;

string = [NSMutableString stringWithCapacity: 50];

[string appendString: @"Hello there"];

[string appendFormat: @"human %d!",39];

NSMutableString *friends;

friends = [NSMutableString stringWithCapacity: 50];

[friends appendString: @"James BethLynn Jack Evan"];

NSRange jackRange;

jackRange = [friends rangeOfString: @"Jack"];

jackRange.length++;   // eat the space that follows

[friends deleteCharactersInRange: jackRange];


19、NSArray和NSMutableArray

A) NSArray(不可改變的數(shù)組,是一個(gè)Cocoa類,用來存儲(chǔ)對(duì)象的有序列表)

NSArray的兩個(gè)限制

首先:它只能存儲(chǔ)Objective-C的對(duì)象,而不能存儲(chǔ)C語言中的基本數(shù)據(jù)類型,如:int, float, enum, struct,或者是NSArray中的隨機(jī)指針

然后:不能存儲(chǔ)nil



1)創(chuàng)建方法

通過類的方法arrayWithObjects:創(chuàng)建一個(gè)新的NSArray

使用方法:

NSArray *array;

array = [NSArray arrayWithObjects:@"one", @"two", @"three",nil];  

//array是以nil結(jié)尾的,這是nil不能存儲(chǔ)的原因

2)常用方法

- (unsigned) count; //獲取數(shù)組包含的對(duì)象個(gè)數(shù)

- (id) objecAtIndex : (unsigned int) index ; //獲取特定索引處的對(duì)象

- componentsSeparatedByString://切分NSArray

- componentsJoinedByString://合并NSString

使用方法:

int i;

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(可變數(shù)組)

1)創(chuàng)建方法,通過類方法arrayWithCapacity創(chuàng)建

+ (id) arrayWithCapacity: (unsigned) numItems;

使用方法:

NSMutableArray *array;

array = [NSMutableArray arrayWithCapacity: 17];

2)常用方法

- (void) addObject: (id) anObject;

- (void) removeObjectAtIndex: (unsigned) index;

使用方法:

for (i = 0; i < 4; i++) {

Tire *tire = [Tire new];

[array addObject: tire];

}

[array removeObjectAtIndex: 1]; //刪除第二個(gè)

C)遍歷數(shù)組的三種方式:通過索引、使用NAEnumerator和快速枚舉

1)索引遍歷  //只有在真的需要索引訪問數(shù)組時(shí)才應(yīng)使用-objectAtIndex,例如跳躍數(shù)組或者同時(shí)遍歷多個(gè)數(shù)組時(shí)

int i;

for (i = 0; i < [array count]; i++) {

NSLog (@"index %d has %@.",i, [array objectAtIndex: i]);

}


2)使用NSEnumerator  //Leopard中被快速枚舉替代

創(chuàng)建方法:通過函數(shù) - (NSEnumerator *) objectEnumerator;

使用方法:

NSEnumerator *enumerator;

enumerator = [array objectEnumerator];  //如果想從后往前瀏覽集合,還有一個(gè)方法reverseEnumerator可以使用

創(chuàng)建后通過while循環(huán),條件是nextObject( 方法原型 - (id) nextObject );

循環(huán)遍歷的程序?yàn)椋?br>
NSEnumerator *enumerator;

enumerator = [array objectEnumerator];

id thingie;

while(thingie = [enumerator nextObject ]) {

NSLog(@“i found %@” , thingie);

}

//注:對(duì)可變數(shù)組進(jìn)行枚舉操作時(shí),不能通過添加和刪除對(duì)象這類方式來改變數(shù)組容器,如果這樣做了,枚舉器會(huì)覺得困惑,為你將會(huì)得到未定義結(jié)果

3)快速枚舉

在Leopard中才開始的,Tiger中不能用

for (NSString *string in array ) {

NSLog(@“i found %@” , string);

}
2010-2-13 19:35:01
21、破除NSArray限制的方法

1)基本類型

a):Cocoa提供了NSNumber類來包裝基本類型

+ (NSNumber *) numberWithChar: (char) value;

+ (NSNumber *) numberWithInt: (int) value;

+ (NSNumber *) numberWithFloat: (float) value;

+ (NSNumber *) numberWithBool: (BOOL) value;

使用方法:

NSNumber *numner;

number = [NSNumber numberWithInt: 42];

[array addObject: number];

[dictionary setObject : number foyKey : @”Bork”];

只要將一些基本類型封裝到NSNumber中,就可以通過下面的實(shí)例方法重新獲得其值

- (char) charValue;

- (int) intValue;

- (float) floatValue;

- (BOOL) boolValue;

- (NSString *) stringValue; //允許自動(dòng)轉(zhuǎn)換

Objective-C不支持自動(dòng)裝箱,要自己動(dòng)手

b):NSNumber是NSValue的子類,NSValue可以包裝任意值

創(chuàng)建新的NSValue

+ (NSValue *) valueWithBytes: (const void *) value

                  objCType: (const char *) type;

使用方法:

NSRect rect = NSMakeRect (1, 2, 30, 40);

NSValue *value;

value = [NSValue valueWithBytes: &rect

      objCType: @encode(NSRect)];  //encode編譯器指令可以接受數(shù)據(jù)類型的名稱并為你生成合適的字符串

[array addObject: value];

可以使用getValue:來提取數(shù)值(注意是get方法,指針)

- (void) getValue: (void *) value; //調(diào)用時(shí),要傳遞的是要存儲(chǔ)這個(gè)數(shù)值的變量的地址

使用方法

value = [array objectAtIndex: 0];

[value getValue: &rect];

Cocoa提供了常用的struct型數(shù)據(jù)轉(zhuǎn)換成NSValue的便捷方法

+ (NSValue *) valueWithPoint: (NSPoint) point;

+ (NSValue *) valueWithSize: (NSSize) size;

+ (NSValue *) valueWithRect: (NSRect) rect;

- (NSPoint) pointValue;

- (NSSize) sizeValue;

- (NSRect) rectValue;

使用方法:

value = [NSValue valueWithRect: rect];

[array addObject: value];

....

NSRect anotherRect = [value rectValue];

2)NSNull

NSNull大概是Cocoa里最簡單的類了,只有一個(gè)方法

+ (NSNull *) null;

可以這樣添加到集合中

[contact setObject: [NSNull null]

forKey: @"home fax machine"];

訪問時(shí):

id homefax;

homefax = [contact objectForKey: @"home fax machine"];

if (homefax == [NSNull null]) {

// ... no fax machine. rats.

}

//[NSNull null]總是返回一樣份數(shù)值,所以你可以使用“==”講該值與其他值進(jìn)行比較……


22、NSDictionary和NSMutableDictionary

A) NSDictionary

字典是關(guān)鍵字和其定義的集合,也被成為散列表或關(guān)聯(lián)數(shù)組,使用的是鍵查詢的優(yōu)化存儲(chǔ)方式

1)創(chuàng)建方法: 使用dictionaryWithObjectsAndKeys:來創(chuàng)建字典

+ (id) dictionaryWithObjectsAndKeys: (id) firstObject, ...;

使用方法:

Tire *t1 = [Tire new];

Tire *t2 = [Tire new];

Tire *t3 = [Tire new];

Tire *t4 = [Tire new];

NSDictionary *tires;

tires = [NSDictionary dictionaryWithObjectsAndKeys:

t1, @"front- left", t2, @"front- right",

t3, @"back- left", t4, @"back- right", nil];

2)常用方法

- (id) objectForKey: (id) aKey;

使用方法:

Tire *tire = [tires objectForKey: @"back- right"];  //如果沒有則會(huì)返回nil值

B) NSMutableDictionary

1)創(chuàng)建方法:

可以向類NSMutableDictionary發(fā)送dictionary消息

也可以使用函數(shù)+ (id) dictionaryWithCapacity: (unsigned int) numItems;

2)常用方法

可以使用setObject:forKey:方法給字典添加元素:

- (void) setObject: (id) anObject forKey: (id) aKey;

- (void) removeObjectForKey: (id) aKey;

使用方法:

NSMutableDictionary *tires;

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"];

//若已經(jīng)存在,則會(huì)用新值替換原有的值

[tires removeObjectForKey: @"back- left"];

23、不要?jiǎng)?chuàng)建NSString、NSArray或NSDictionary的子類,因?yàn)樵贑ocoa中,許多類實(shí)際上是以類簇的方式實(shí)現(xiàn)的,即他們是一群隱藏在通用接口之下的與實(shí)現(xiàn)相關(guān)的類

24、Foundation實(shí)例 //查找文件

A)使用枚舉遍歷

int main (int argc, const char *argv[])

{

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];   //自動(dòng)釋放池

NSFileManager *manager; //Cocoa中有很多類都是單實(shí)例構(gòu)架,即只需要一個(gè)實(shí)例,你真的只需要一個(gè)文件管理器

manager = [NSFileManager defaultManager]; // defaultManager方法創(chuàng)建一個(gè)屬于我們的NSFileManager對(duì)象

NSString *home;

home = [@"~" stringByExpandingTildeInPath]; // stringByExpandingTildeInPath方法可將~替換成當(dāng)前用戶的主目錄

NSDirectoryEnumerator *direnum; //NSEnumerator的子類

direnum = [manager enumeratorAtPath: home]; //創(chuàng)建一個(gè)枚舉條件

NSMutableArray *files;

files = [NSMutableArray arrayWithCapacity: 42]; //把搜索的結(jié)果作為文件存儲(chǔ)

NSString *filename;

while (filename = [direnum nextObject]) {//調(diào)用nextObject時(shí),都會(huì)返回該目錄中的一個(gè)文件的另一個(gè)路徑,也可搜索子目錄

if ([[filename pathExtension]  // pathExtension輸出文件的擴(kuò)展名(去掉了前面的點(diǎn).)

isEqualTo: @"jpg"]) {

[files addObject: filename];

}

}

NSEnumerator *fileenum;

fileenum = [files objectEnumerator];

while (filename = [fileenum nextObject]) {

NSLog (@"%@", filename);

}

[pool drain];

return (0);

} // main

B)使用快速遍歷

int main (int argc, const char * argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSFileManager *manager;

manager = [NSFileManager defaultManager];

NSString *home;

home = [@"~" stringByExpandingTildeInPath];

NSMutableArray *files;

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);

}
2010-2-13 19:35:36
六:內(nèi)存管理

25、Cocoa采用引用計(jì)數(shù)(reference counting)的技術(shù),有時(shí)稱為保留計(jì)數(shù)。

每個(gè)對(duì)象有一個(gè)與之相關(guān)聯(lián)的整數(shù),稱做為他的引用計(jì)數(shù)器或保留計(jì)數(shù)器

- (id) retain;  

- (void) release;

- (unsigned) retainCount;  //當(dāng)前值

26、對(duì)象所有權(quán)的處理

- (void) setEngine: (Engine *) newEngine

{

[newEngine retain];

[engine release];

engine = newEngine;

} // setEngine

原則:先保存新對(duì)象,再釋放員對(duì)象

27、自動(dòng)釋放

程序會(huì)自動(dòng)建立一個(gè)自動(dòng)釋放池(autorelease pool),他是一個(gè)存放實(shí)體的池(集合),這些實(shí)體可能是對(duì)象,能夠被自動(dòng)釋放。

自動(dòng)釋放池創(chuàng)建代碼

NSAutoreleasePool  *pool;

pool = [[NSAutoreleasePool  alloc]  init];

……

[pool  release];

NSObject類提供了一個(gè)antorelease方法:

- (id) autorelease;

//該方法預(yù)先定義了一條在將來某個(gè)時(shí)間發(fā)送的release消息,其返回值是接收消息的對(duì)象,retain采用了相同的技術(shù),使嵌套調(diào)用更加容易。

//當(dāng)給一個(gè)對(duì)象發(fā)送autorelease消息時(shí),實(shí)際上是將對(duì)象添加到NSAutoreleasePool方法中,當(dāng)自動(dòng)釋放池銷毀了,會(huì)像該池中的所有對(duì)象發(fā)送release消息

例如

- (NSString *) description

{

NSString *description;

description = [[NSString alloc]

  initWithFormat: @"I am %d years old", 4];

return ([description autorelease]); //因?yàn)閐escriptor方法首先創(chuàng)建了一個(gè)新的字符串對(duì)象,然后自動(dòng)釋放該對(duì)象,最后將其返回給NSLog()函數(shù)

} // description

29、Cocoa內(nèi)存管理原則

如果使用new,alloc或copy操作獲得一個(gè)對(duì)象,則該對(duì)象的保留計(jì)數(shù)器值加1,release減1

如果通過任何其他方法獲得一個(gè)對(duì)象,則假設(shè)該對(duì)象的保留計(jì)數(shù)器值為1,而且已經(jīng)被設(shè)置為自動(dòng)釋放

如果保留了某個(gè)對(duì)象,則必須保持retain方法和release方法使用的次數(shù)相同

30、NSColor的blueColor方法返回一個(gè)全局單例對(duì)象

31、一直擁有對(duì)象

希望在多個(gè)代碼段中一直擁有某個(gè)對(duì)象常見的方法有:在其他對(duì)象中使用這些變量,將它們加入到諸如NSArray或NSDictionary等集合中,或?qū)⑵渥鳛槿肿兞渴褂?罕見)

如果你使用new,alloc或copy方法獲得一個(gè)對(duì)象,則不需要執(zhí)行任何其他操作,他將一直存在,你只要在擁有該對(duì)象的dealloc方法中釋放該對(duì)象就可

- (void) doStuff

{

// flonkArray is an instance variable

flonkArray = [NSMutableArray new]; // count: 1

} // doStuff

- (void) dealloc

{

[flonkArray release]; // count: 0

[super dealloc];

} // dealloc

32、Cocoa程序才開始處理事件之前創(chuàng)建一個(gè)自動(dòng)釋放池,并在事件處理結(jié)束后銷毀該自動(dòng)釋放池

33、保證內(nèi)存占用比較小的一種方法,分段處理

int i;

for (i = 0; i < 1000000; i++) {

id object = [someArray objectAtIndex: i];

NSString *desc = [object description];

// and do something with the description

}

節(jié)省內(nèi)存的方法:

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

int i;

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]

//自動(dòng)釋放池以棧的形式存在

34、Objective-C 2.0的垃圾回收機(jī)制,是一個(gè)可選擇啟用的功能,項(xiàng)目信息屬性轉(zhuǎn)到Build選項(xiàng)卡,在Objective-C Garbage Collection選項(xiàng)選成Required [-fobjc-gc- only]即可

但注意:iPhone里面不能用



七:對(duì)象的初始化

35、兩種方法

[類名 new]  //不熟悉Cocoa的開發(fā)人員使用的輔助方法

[[類名 alloc] init]   //主要使用方法

36、分配(allocation)

向某個(gè)發(fā)送

內(nèi)存區(qū)域 :全部初始化為0

BOOL :NO

int : 0

float : 0.0

指針 : nil

37、兩種格式

Car *car = [[Car alloc] init];  //推薦使用,這種嵌套調(diào)用非常重要,因?yàn)槌跏蓟椒ǚ祷氐膶?duì)象可能與分配的對(duì)象不同,雖然很奇怪,但是它的確會(huì)發(fā)生

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繼承的類調(diào)用超類的初始化方法,可以使NSObject執(zhí)行所需的任何操作,以便對(duì)象能夠響應(yīng)消息并處理保留計(jì)數(shù)器,而從其他類繼承的類調(diào)用超類的初始化方法,可以使子類有機(jī)會(huì)實(shí)現(xiàn)自己全新的初始化

//實(shí)例變量所在的位置到隱藏的self參數(shù)的距離是固定的,如果從init方法返回一個(gè)新對(duì)象,則需要更新self,以便其后的任何實(shí)例變量的引用可以被映射到正確的位置,這也是self = [super init]使用的原因,記住,這個(gè)賦值操作只影響init方法中self的值,而不影響該范圍以外的任何內(nèi)容

// if (self = [super init])使用的原因,如果[super init]返回的結(jié)果是nil,則主體不會(huì)執(zhí)行,只是賦值和檢測非零值結(jié)合的方法,沿襲自C風(fēng)格

39、便利初始化函數(shù)  //也可以自己構(gòu)建

- (id) initWithFormat: (NSString *) format, ...;

- (id) initWithContentsOfFile: (NSString *) path;  //打開指定路徑上的文件,讀取文件內(nèi)容,并使用文件類內(nèi)容初始化一個(gè)字符串

使用方法:

string = [[NSString alloc]

  initWithFormat: @"%d or %d", 25, 624];

string = [[NSString alloc]

  initWithContentsOfFile: @"/tmp/words.txt"];  

構(gòu)造便利初始化函數(shù)

例如

在@interface Tire: NSObject中添加方法聲明

- (id) initWithPressure : (float) pressure

                  treadDepth: (float) treadDepth;

在@implementation Tire中實(shí)現(xiàn)該方法

- (id) initWithPressure: (float) p

           treadDepth: (float) td

{

if (self = [super init]) {

pressure = p;

treadDepth = td;

}

return (self);

} // initWithPressure:treadDepth:

這樣就完成了初始化函數(shù)的定義,分配,初始化一體完成

Tire *tire;

tire = [[Tire alloc]

initWithPressure: 23 + i

treadDepth: 33 - i];
2010-2-13 19:36:05
39、如果用NSMutableArray代替C數(shù)組,則就不用執(zhí)行邊界檢查

40、指定初始化函數(shù)

有的時(shí)候定義了太多的初始化函數(shù)時(shí),會(huì)出現(xiàn)一些細(xì)微的問題

例如下面的程序

@interface Tire : NSObject

{

float pressure;

float treadDepth;

}

- (id) initWithPressure: (float) pressure;

- (id) initWithTreadDepth: (float) treadDepth; //新增加的兩個(gè)初始化函數(shù)

- (id) initWithPressure: (float) pressure

treadDepth: (float) treadDepth;

- (void) setPressure: (float) pressure;

- (float) pressure;

- (void) setTreadDepth: (float) treadDepth;

- (float) treadDepth;

@end // Tire

//聲明了三個(gè)初始化函數(shù)

//新聲明的初始化函數(shù)的實(shí)現(xiàn)

- (id) initWithPressure: (float) p

{

if (self = [super init]) {

pressure = p;

treadDepth = 20.0;

}

return (self);

} // initWithPressure

- (id) initWithTreadDepth: (float) td

{

if (self = [super init]) {

pressure = 34.0;

treadDepth = td;

}

return (self);

} // initWithTreadDepth

問題來了

子類化問題:

@interface AllWeatherRadial : Tire

{

float rainHandling;

float snowHandling;

}

- (void) setRainHanding: (float) rainHanding;

- (float) rainHandling;

- (void) setSnowHandling: (float) snowHandling;

- (float) snowHandling;

@end // AllWeatherRadial

//枯燥的存取函數(shù)

- (void) setRainHandling: (float) rh

{

rainHandling = rh;

} // setRainHandling

- (float) rainHandling

{

return (rainHandling);

} // rainHandling

- (void) setSnowHandling: (float) sh

{

snowHandling = sh;

} // setSnowHandling

- (float) snowHandling

{

return (snowHandling);

} // snowHandling

- (NSString *) description

{

NSString *desc;

desc = [[NSString alloc] initWithFormat:

@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",

[self pressure], [self treadDepth],

[self rainHandling],

[self snowHandling]];

return (desc);

} // description

//main.m函數(shù)中實(shí)現(xiàn)

int i;

for (i = 0; i < 4; i++) {

AllWeatherRadial *tire;

tire = [[AllWeatherRadial alloc] init];

[car setTire: tire

atIndex: i];

[tire release];

}

運(yùn)行的結(jié)果是下面這個(gè)樣子的

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!

//注:默認(rèn)情況下初始化函數(shù)只會(huì)按最容易實(shí)現(xiàn)的方式去運(yùn)行,這不是我要的結(jié)果,并且是錯(cuò)誤的結(jié)果

解決辦法:指定初始化函數(shù)(designated initializer)

- (id) init

{

if (self = [self initWithPressure: 34

  treadDepth: 20]) {

}

return (self);

} // init

- (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類的初始化函數(shù)

- (id) initWithPressure: (float) p

           treadDepth: (float) td

{

if (self = [super initWithPressure: p

treadDepth: td]) {

rainHandling = 23.7;

snowHandling = 42.5;

}

return (self);

} // initWithPressure:treadDepth


此時(shí)我們?cè)龠\(yùn)行可以得到這樣的結(jié)果

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!
2010-2-13 19:36:38
八:屬性

41、屬性(property)是Objective-C 2.0中引入的,為了方便的編寫存取方法

42、屬性的使用方法

1)聲明方法的簡化

//舊的表示方法

#import <Foundation/Foundation.h>

#import "Tire.h"

@interface AllWeatherRadial : Tire {

float rainHandling;

float snowHandling;

}

- (void) setRainHandling: (float) rainHanding;

- (float) rainHandling;

- (void) setSnowHandling: (float) snowHandling;

- (float) snowHandling;

@end // AllWeatherRadial

//用屬性表示后

#import <Foundation/Foundation.h>

#import "Tire.h"

@interface AllWeatherRadial : Tire {

float rainHandling;

float snowHandling;

@property float rainHandling;  //表明該類有一個(gè)名為rainHanding的float型屬性,你可以通過-setRainHanding: 來設(shè)置屬性,通過-rainHanding來訪問屬性

@property float snowHandling;

@end // AllWeatherRadial

}

//@property預(yù)編譯命令的作用是自動(dòng)聲明屬性的setter和getter方法

//屬性的名稱不必與實(shí)例變量名稱相同,但是一般都是相同的

2)實(shí)現(xiàn)方法的簡化

//百年老字號(hào)

#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 = rh;

} // setRainHandling

- (float) rainHandling

{

return (rainHandling);

} // rainHandling

- (void) setSnowHandling: (float) sh

{

snowHandling = sh;

} // setSnowHandling

- (float) snowHandling

{

return (snowHandling);

} // snowHandling

- (NSString *) description

{

NSString *desc;

desc = [[NSString alloc] initWithFormat:

@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",

[self pressure], [self treadDepth],

[self rainHandling],

[self snowHandling]];

return (desc);

} // description

@end // AllWeatherRadial

//改進(jìn)后的方法

#import "AllWeatherRadial.h"

@implementation AllWeatherRadial

@synthesize rainHandling;

@synthesize snowHandling;

- (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;

desc = [[NSString alloc] initWithFormat:

@"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f",

[self pressure], [self treadDepth],

[self rainHandling],

[self snowHandling]];

return (desc);

} // description

@end // AllWeatherRadial

//@synthesize也是一種新的編譯器功能,表示“創(chuàng)建該屬性的訪問器”

//當(dāng)遇到@synthesize rainHandling;時(shí),編譯器將輸出-setRainHanding:和- rainHanding方法的已編譯代碼

43、點(diǎn)表達(dá)式

點(diǎn)表達(dá)式(.),若出現(xiàn)在等號(hào)(=)左邊,該屬性名稱的setter方法將被調(diào)動(dòng),多出現(xiàn)在對(duì)象變量右邊,則該屬性名冊(cè)和那個(gè)的getter方法將被調(diào)用

//注:特性的點(diǎn)表達(dá)式和流行的鍵/值編碼的后臺(tái)工作沒有聯(lián)系

44、特性擴(kuò)展

特性同樣適用于int、char、BOOL和struct類型

(所有者對(duì)象保留被擁有的對(duì)象,而不是被擁有的對(duì)象保留所有者對(duì)象)

//可以使用一些聲明,用于內(nèi)存處理(那個(gè)是用垃圾回收機(jī)制的路過)

@property (copy) NSString *name;

@property (retain) Engine *engine;

45、特性名和實(shí)例變量名字不相同的情況

@interface Car : NSObject {

NSString *appellation;

NSMutableArray *tires;

Engine *engine;

}

@property (copy) NSString *name;

@property (retain) Engine *engine;

//然后,修改@synthesize指令

@synthesize name = appellation;

編譯器扔將創(chuàng)建-setName:和- name方法,但是在實(shí)現(xiàn)中卻是用實(shí)例變量application

//這樣做會(huì)有錯(cuò)誤,因?yàn)槲覀冎苯釉L問的實(shí)例變量name已經(jīng)被修改了,我們既可以選擇搜索替換name,也可以將直接的實(shí)例變量訪問修改為使用訪問器訪問,在init方法中,將

name = @”Car”;

修改為:

self.name = @”Car” ;   //[self setName : @”Car”];

在dealloc中,使用一種高明的技巧:

self.name = nil;  //使用nil參數(shù)調(diào)用setName:方法

生成的訪問器將自動(dòng)釋放以前的name對(duì)象,并使用nil替代name

最后修改-description方法需要使用第一次被修改的NSLog()函數(shù):

NSLog(@”%@ has:” , self.name);
2010-2-13 19:37:00
46、只讀特性

//默認(rèn)的特性是支持可寫可讀的,原型如下

@property (readwrite, copy) NSString *name;

@property (readwrite, retain) Engine *engine;

//但為了簡便,為了消除重復(fù)

//只讀屬性的設(shè)置

@interface Me : NSObject {

float shoeSize;

NSString *licenseNumber;

}

@property (readonly) float shoeSize;

@property (readonly) NSString *licenseNumber;

@end

//這類編譯器只會(huì)生成getter方法,不會(huì)有setter方法

47、特性的局限性

//不支持那么需要接受額外參數(shù)的方法

- (void) setTire: (Tire *) tire

atIndex: (int) index;

- (Tire *) tireAtIndex: (int) index;

//這樣的只能使用百年老字號(hào)





九:類別

48、可以利用Objective-C的動(dòng)態(tài)運(yùn)行時(shí)分配機(jī)制,為現(xiàn)有的類添加新方法---這就叫類別(category)

//特別是那些不能創(chuàng)建之類的類,很是cool

49、創(chuàng)建類別

//如果你希望想一個(gè)array或者dictionary里面添加一個(gè)個(gè)數(shù)字,你需要一個(gè)個(gè)的封裝,如果多,你會(huì)瘋掉,可以為string類添加一個(gè)類別來完成這項(xiàng)工作

1)聲明對(duì)象 //與類的聲明格式類似

@interface NSString (NumberConvenience)

- (NSNumber *) lengthAsNumber;

@end // NumberConvenience

//我們正在向String類里面添加一個(gè)NumberConvenience方法,可以添加很多個(gè),只要名稱不相同

2)實(shí)現(xiàn)部分

@implementation NSString (NumberConvenience)

- (NSNumber *) lengthAsNumber

{

unsigned int length = [self length];  //獲得字符串的長度

return ([NSNumber numberWithUnsignedInt: length]);

} // lengthAsNumber

@end // NumberConvenience


現(xiàn)在就可以用了

int main (int argc, const char *argv[])

{

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

NSMutableDictionary *dict;

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);

} // main

//任何NSString類都將響應(yīng)lengthAsNumber消息,正式這種兼容性使類別稱為一個(gè)非常偉大的概念,不需要?jiǎng)?chuàng)建NSString的之類,類別同樣可以完成同樣的工作

50、類別的局限性

第一:無法向類別里面添加新的實(shí)例變量,類別里面沒有位置容納實(shí)例變量//也可以是用dictionary封裝,但是不劃算

第二:若名稱沖突,類別的優(yōu)先級(jí)更高(一般都是加一個(gè)前綴避免名稱沖突)

51、類別的作用

Cocoa中類別主要用于3個(gè)目的

1)將類的實(shí)現(xiàn)分散到多個(gè)不同的文件或不同構(gòu)架中

用類別分離文件時(shí)注意類別的寫法,一個(gè)類的類別才能實(shí)現(xiàn)這個(gè)類的方法

2)創(chuàng)建對(duì)私有方法的前向引用

有些聲明不需要寫在.h文件中,因?yàn)橛械臅r(shí)候這個(gè)只是本類的一個(gè)小的實(shí)現(xiàn),聲明太麻煩,而且讓code reader比較難理解,就可以在.m中用類別聲明一下

@interface Car (PrivateMethods)


- (void) moveTireFromPosition: (int) pos1

  toPosition: (int) pos2;


@end //private Methods


3)向?qū)ο筇砑臃钦絽f(xié)議

非正式協(xié)議表示這里有一些你可能希望實(shí)現(xiàn)的方法,因此你可以使用它們更好的完成工作



52、將類的實(shí)現(xiàn)分散到多個(gè)不同的文件或不同架構(gòu)中

看文檔中的NSWindows類

@interface NSWindow : NSResponder

然后是一大堆類別:

@interface NSWindow(NSKeyboardUI)

@interface NSWindow(NSToolbarSupport)

@interface NSWindow(NSDrag)

@interface NSWindow(NSCarbonExtensions)

@interface NSObject(NSWindowDelegate)

這樣就就可以把一個(gè)大的文件分開使用,看起來方便,實(shí)用



53、run循環(huán)

[[NSRunLoop currentRunLoop] run];

是一種cocoa構(gòu)造,它一直處于阻塞狀態(tài)(即不執(zhí)行任何處理),知道某些有趣的事情發(fā)生為止

//這個(gè)run方法將一直運(yùn)行而不會(huì)返回,后面的代碼將一直不執(zhí)行



54、委托和類別

委托強(qiáng)調(diào)類別的另一種應(yīng)用:被發(fā)送給委托對(duì)象的方法可以聲明為一個(gè)NSObject的類別。NSNetService委托方法的聲明如下

@interface NSObject

(NSNetServiceBrowserDelegateMethods)


- (void) netServiceBrowser: (NSNetServiceBrowser *) browser

didFindService: (NSNetService *) service

moreComing: (BOOL) moreComing;


- (void) netServiceBrowser: (NSNetServiceBrowser *) browser

  didRemoveService: (NSNetService *) service

moreComing: (BOOL) moreComing;


@end

通過這些方法聲明為NSObject的類型,NSNetServiceBrowser的實(shí)現(xiàn)可以將這些消息之一發(fā)送個(gè)任何對(duì)象,無論這些對(duì)象實(shí)際上屬于哪個(gè)類。這意味著,只要實(shí)現(xiàn)了委托方法,任何類的對(duì)象都可以成為委托對(duì)象

通過這種方法可以不繼承(c++)和不實(shí)現(xiàn)某個(gè)特定的接口(java),就可以作為委托對(duì)象使用



55、NSObject提供了一個(gè)名為respondsToSelector:的方法,該方法訪問對(duì)象以確定其是否能夠響應(yīng)某個(gè)特定的消息


56、復(fù)制的種類有Shallow Copy和deep copy

Shallow Copy不復(fù)制引用對(duì)象,新復(fù)制的對(duì)象只指向指向現(xiàn)有的引用對(duì)象

deep copy將復(fù)制所有的引用對(duì)象


57,[self class]妙用

Car *carCopy = [[[self class] allocWithZone: zone] init];

可以通過self的類型來判斷運(yùn)行結(jié)果,子類的用這個(gè)函數(shù)就是子類的結(jié)果


58,NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow: -(24 * 60 * 60)];

獲取一個(gè)時(shí)間段以前的一個(gè)時(shí)間,dateWithTimeIntervalSinceNow 接受一個(gè)NSTimeInterval參數(shù),是一個(gè)雙精度值,以秒為單位


59.NSData 和 char*的轉(zhuǎn)化

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]);  //格式化輸出要的內(nèi)容


60,有些屬性文件(特別是首選項(xiàng)文件)是以二進(jìn)制格式存儲(chǔ)的,通過使用plutil命令:plutil -convert xml1 filename.plist可以轉(zhuǎn)化成人們可讀的形式
2010-2-13 19:37:32
61,[phrase writeToFile: @"/tmp/verbiage.txt"  atomically: YES];的atomically 是用于通知cocoa是否應(yīng)該首先將文件內(nèi)容保存在臨時(shí)文件中,當(dāng)文件保存成功后,再將該臨時(shí)文件和原始文件交換


62,編碼對(duì)象

#import <Foundation/Foundation.h>


@interface Thingie : NSObject <NSCoding> {

    NSString *name;

    int magicNumber;

    float shoeSize;

    NSMutableArray *subThingies;

}

@property (copy) NSString *name;

@property int magicNumber;

@property float shoeSize;

@property (retain) NSMutableArray *subThingies;


- (id)initWithName: (NSString *) n

       magicNumber: (int) mn  

          shoeSize: (float) ss;


@end // Thingie



@implementation Thingie

@synthesize name;

@synthesize magicNumber;

@synthesize shoeSize;

@synthesize subThingies;


- (id)initWithName: (NSString *) n

       magicNumber: (int) mn  

          shoeSize: (float) ss {

    if (self = [super init]) {

        self.name = n;

        self.magicNumber = mn;

        self.shoeSize = ss;

        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的兩個(gè)子類NSKeyedArchiver和NSKeyedUnarchiver

    NSData *freezeDried;

    freezeDried = [NSKeyedArchiver archivedDataWithRootObject: thing1];

    [thing1 release];

    thing1 = [NSKeyedUnarchiver unarchiveObjectWithData: freezeDried];

    NSLog (@"reconstituted thing: %@", thing1);

   

    Thingie *anotherThing;

    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);

} // main


63,KVC(Key Value Code)

Advantage one:

NSLog (@"horsepower is %@", [engine valueForKey: @"horsepower"]); //這個(gè)會(huì)自動(dòng)打包成NSNumber或NSValue

[engine setValue: [NSNumber numberWithInt: 150] //這個(gè)使用的時(shí)候要自己打包

  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"];//要是路徑是一個(gè)數(shù)組就只能獲取一個(gè)數(shù)組,不能只獲取一個(gè)

NSLog (@"pressures %@", pressures);


Advantage two

NSNumber *count;

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

NSLog (@"We have %@ cars", count);

NSNumber *sum;

sum = [garage valueForKeyPath: @"cars.@sum.mileage"];

NSLog (@"We have a grand total of %@ miles", sum);

NSNumber *avgMileage;

avgMileage = [garage valueForKeyPath: @"cars.@avg.mileage"];

NSLog (@"average is %.2f", [avgMileage floatValue]);

NSNumber *min, *max;

min = [garage valueForKeyPath: @"cars.@min.mileage"];

max = [garage valueForKeyPath: @"cars.@max.mileage"];

NSLog (@"minimax: %@ / %@", min, max);

NSArray *manufacturers;

manufacturers = [garage valueForKeyPath: @"cars.@distinctUnionOfObjects.make"];

NSLog (@"makers: %@", manufacturers);

//另外,union 運(yùn)算符指一組對(duì)象的并集

//distinct用于刪除重復(fù)的內(nèi)容

//遺憾的一點(diǎn)就是不能添加自的運(yùn)算符


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",

nil];

[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);

這里的標(biāo)量值mileage中的nil表示的是什么0?-1?pi?cocoa無法知道,可以再car類里面重寫

- (void) setNilValueForKey: (NSString *) key {

if ([key isEqualToString: @"mileage"]) {

mileage = 0;

} else {

[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
2010-2-13 19:37:51
64、Cocoa中提供NSPredicate的類,它用于指定過濾的條件

Cocoa用NSPredicate描述查詢的方式,原理類似于在數(shù)據(jù)庫中進(jìn)行查詢

計(jì)算謂詞:

//基本的查詢

NSPredicate *predicate;

predicate = [NSPredicate predicateWithFormat: @"name == 'Herbie'"];

    BOOL match = [predicate evaluateWithObject: car];

    NSLog (@"%s", (match) ? "YES" : "NO");


//在整個(gè)cars里面循環(huán)比較

    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"];

    NSArray *results;

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);


//含有變量的謂詞

    NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@"name == $NAME"];

    NSDictionary *varDict;

    varDict = [NSDictionary dictionaryWithObjectsAndKeys:

               @"Herbie", @"NAME", nil];

    predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];

    NSLog(@"SNORGLE: %@", predicate);

    match = [predicate evaluateWithObject: car];

  NSLog (@"%s", (match) ? "YES" : "NO");

//注意不能使用$VARIABLE作為路徑名,因?yàn)樗荡碇?br>

//謂詞字符竄還支持c語言中一些常用的運(yùn)算符

    /*

*>: 大于

*>=和=>: 大于或等于

*<: 小于

*<=和=<: 小于或等于

*!=和<>: 不等于

*括號(hào)運(yùn)算符,AND,OR,NOT,&&,||,! (可以不區(qū)分大小寫,但建議一致)

*/

    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"]);


//強(qiáng)大的數(shù)組運(yùn)算符

    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運(yùn)算符

    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

//附加符號(hào),[c],[d],[cd],c表示不區(qū)分大小寫,d表示不區(qū)分發(fā)音字符,cd表示什么都不區(qū)分

    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運(yùn)算符(通配符)

    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);

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多