Objective-C 2.0(三)memory&Foundation Framework Classes

Objective-C 2.0(三)memory&Foundation Framework Classes:2009年08月19日星期三

Objective-C 2.0(一)Objects & Messaging的(Q)(R)(S)及Objective-C 2.0(二)Class將Objective-C的Class掃描了一次,每一個主題試作一個SDK 3.0 Xcode上的例子,本文、Objective-C 2.0(三)memory&Foundation Framework Classes,將探討memory及Foundation Framework Classes。這三篇文章將Objective-C Beginner's Guide的中文掃描了一次並參考Objective-C 2.0 Programming Language 及SDK 3.0 Xcode/Help/documentation/SDK3.0 Library ,試做了Objective-C Beginner's Guide的中文所有的例子。這些改寫好的SDK3.0/Xcode例子,已上傳iPhone課程論壇,檔名0816iPhoneStudyGroup.zip0830iPhoneStudyGroup.zip

本文的主要根據是Objective-C Beginner's Guide的中文英文網站,有source code, 下載後稍加修改即可用在Xcode開發環境中(如何改?見Objective-C 2.0(一)Objects & Messaging(Q)(二))。同以Apple的Objective-C 2.0 Programming Language 為輔,在此亦可找到同名的章節Defining a Class、Classes。Language summary也很重要,Class亦在其中。

開始之前先將Objective-C的Language Summary Link放在此。

(A)問:Retain及release是NSObject的protocol,如何使用?詳見Objective-C Beginner's Guide的中文Retain及release

答:每個object都有一個reference count,alloc將reference count 設為1,retain將object內的reference count加一,release將object內的reference count減一,當object的reference count減到0時,自動call 該object的dealloc,歸還memory。

型式:

object = [class alloc] // reference count set to 1

[object retain]; // reference count incremented by 1

[object release]; // reference count decremented by 1

[object retainCount]; //return the reference count of the object

說明:見型式內的comment

練習:本段class的練習已作成Xcode可執行的project,名稱為retainObjc。

(B)問:如何使用dealloc?詳見Objective-C Beginner's Guide的中文dealloc

答:dealloc一般會release instance variable,並且[super dealloc] 以便free所有super class的memory。

練習:本段class的練習已作成Xcode可執行的project,名稱為deallocObjc。

在練習中,特別注意setFirst內的三行:

[f retain];

[first release];

first =f;

  1. 這三行的次序不能改變,因f及first均為pointer to object,
    1. 若先[first release];則first這instance variable就被destruct了。
    2. 若先first =f;則無法做[first release];以便free first指向的NSString這片memory。
  2. 因為是pointer assignment,所以需先[f retain];將其reference count加一,這裡的f即是deallocObjcAppDelegate.m內的[first release];,先retain,未來[first release]時,即無法destruct這個pointer所指向的NSString。

(C)問:什麼是autorelease pool? 詳見Objective-C Beginner's Guide的中文autorelease pool

答:當創造了一個AutoReleasePool後,@"constant string"會自動進這個pool。stringWithString這種method call也會進pool。只有alloc method 如 [[NSString alloc] initWithString: @"String"] 不使用 auto release pool。

型式:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

[object autorelease]; //並不立刻release,只是記錄reference count減一,直到 [pool release];才算加減總帳。

練習:本段class的練習已作成Xcode可執行的project,共有兩個:

名稱為autoreleaseObjc:demo auto release 影響reference count的情形。

名稱為autoreleasepoolObjc:demo autorelease pool。

(D)問:Foundation Framework是什麼?

答: Foundation Framework包含一堆Classes。Framework裡有物件組(collections)、網路(Networking)、執行緒(Threading)。

(E)問:NSArray?詳見Objective-C Beginner's Guide的中文NSArray。整個物件詳見SDK 3.0/Xcode/Help/Documentation/iPhone OS 3.0 Library/search for NSArray。

答:有NSArray及NSMutableArray,兩者合稱序列物件組(array collection),Mutable--善變的--表示可以變,NSArray則像是constant。NSMutableArray是NSArray的subClass。

NSArray:

NSCopying,isEqual。

count,objectAtIndex(index從0開始)。

initWithObjects:見下建構型式。return 一個NSArray。

objectEnumerator:回傳一個指向NSEnumerator object的pointer。

NSMutableArray:

NSMutableCopying,

addObjectsFromArray

sortUsingSelector:以下這段語法是說,sort anArrayObject,使用的比較大小方式是以@selector(caseInsensitiveCompare:)所指定的caseInsensitiveCompare這個方法。

語法[anArrayObject sortUsingSelector:@selector(caseInsensitiveCompare:)];

caseInsensitiveCompare:不分英文大小寫的比較方法。

addObject

型式:

建構:[[NSArray alloc] initWithObjects: @"Me", @"Myself", @"I", nil]; // [[NSArray alloc] initWithObjects:Obj1,Obj,....nil];

練習:本段class的練習已作成Xcode可執行的project,名稱為arrayObjc。

練習中用到了:NSEnumerator的nextObject,NSArray中的objectEnumerator、initWithObjects,NSMutableArray的addObject、addObjectsFromArray、sortUsingSelector,@selector。

(F)問:NSDictionary?詳見Objective-C Beginner's Guide的中文NSDictionary。整個物件詳見SDK 3.0/Xcode/Help/Documentation/iPhone OS 3.0 Library/search for NSDictionary。

答:與NSArray類似,有NSDictionary及NSMutableDictionary兩種,兩者合稱字典(dictionary),Mutable--善變的--表示可以變,NSDictionary則像是constant。NSMutableDictionary是NSDictionary的subClass。這就像一本字典,概念是(key, value),用key來搜尋出所需的value。

NSDictionary:

initWithObjectsAndKeys:

NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: @"one", [NSNumber numberWithInt: 1], @"two",[NSNumber numberWithInt: 3], nil];

-(id) initWithObjectsAndKeys:(id) firstObject, ....

.....

第一個是firstObject的key,接著是secondObject、key,之後即為object、key的配對,直到出現nil為止。

注意:事實上nil一定出現在object的位置。若key是nil,會產生NSInvalidArgumentException。

NSMutableDictionary:

objectForKey:以下的key是由key = [objectOfNSEnumerator nextObject]; 產生的

[[[objectOfNSMutableDictionary objectForKey:key ] description] cString];

setObject: forKey:[mutable setObject:@"Tom" forKey:@"tom@jones.com"];

練習:本段class的練習已作成Xcode可執行的project,名稱為dictionaryObjc。

練習中用到了:NSEnumerator的nextObject,NSDictionary中的keyEnumerator、initWithObjectsAndKeys,NSString中的cString、cStringWithEncoding、NSASCIIStringEncoding。

注意:在dictionaryObjcAppDelegate.m中print function裡,因每個cString都有warning,將第一個cString改為cStringWithEncoding:NSASCIIStringEncoding。

(G)問:NSString?詳見SDK 3.0/Xcode/Help/Documentation/iPhone OS 3.0 Library/search for NSString。

答:曾用過的NSString method如下:

cString:return a C string。

cStringWithEncoding:NSASCIIStringEncoding:retrun a C string,i.e. (char *)。

(H)問:NSEnumerator?詳見SDK 3.0/Xcode/Help/Documentation/iPhone OS 3.0 Library/search for NSEnumerator。

答:曾用過的NSEnumerator method如下:

NSEnumerator *enumerator = [array objectEnumerator];

nextObject:return the next object to be enumberated. e.g. array的一個element.

(I)@property的用法?

答:@property可簡化getter/setter的coding。在@interface內用@property float value;及@ implementation內用"@synthesize value;", 自動由compiler產生 -(float)value; (getter)及-(void)setValue:(float)newValue;(setter)兩method。

Declaration 的型式:

@interface myClass :NSObject {

float value;

}

@property float value;

@end

說明:@property float value;等於下面兩行。

-(float)value;

-(void)setValue:(float)newValue;

Implementation型式:

@interface MyClass:NSObject{

@synthesize value;

}

說明:加上@synthesize value;這一行,compiler會自動synthesize(組合)value及setValue這兩個method,不需要自己動手寫。

複雜declaration型式:

@property (attribute1, attribute2 ... ) type name;

例:@property (getter = getValue, setter = setTheValue ) float value;這個例子是指定getter名為getValue(而非value),setter名為setTheValue(而非setValue)。