Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... ·...

19
Programming in Objective-C Part II - Framework Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Transcript of Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... ·...

Page 1: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Programming in Objective-C

Part II - Framework

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 2: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Chapter 8!หลังจากที่เราไดเริ่มมีพ้ืนฐานการเขียนโปรแกรมดวยภาษา Objective-C เชนการเรียนคลาส ประกาศเมธอด ในบทนี้เราจะกาวเขาสูการใชงานของ Cocoa Framework ซึ่งเปนหัวใจหลักสำคัญในการเขียนโปรแกรมดวยภาษา Objective-C แต กอนจะเริ่มสวนที่สองของหนังสือเลมนี้ เราควรทำความรูจักกับเฟรมเวิรก (Framework) กันสักนิดวาคืออะไร “เฟรมเวิรก” สำหรับ Mac OS X แลวหมายถึงการนำเอา Library ตางๆมารวมไวกัน เหมือนกับการเอาหนังสือเรื่องแสง, แรงโนมถวง และ โมเมนตั้ม มาแพ็ครวมกันแลวเรียกวาหนังสือเหลานี้เปนหนังสือฟสิกส V ถายังจำกันไดในบทแรกๆ เก่ียวกับประวัติความเปนมาของ Objective-C หลังจากที่ Apple ตกลงซื้อ NEXTSTEP ก็ไดนำเอาเฟรมเวิรกของบริษัท NEXTSTEP มาใชงานและพัฒนาใหมกลายเปน Cocoa ดังนั้นชื่อของคลาสตางๆเฟรมเวิรกสวนมากจึงขึ้นตนดวย NS ซึ่งเปนตัวยอของ NEXTSTEP นั่นเอง นอกจากนี้แลว Apple ยังมเีฟรมเวิรกอีกตัวคือ Carbon 1 ซึ่งเปน Framework ของภาษา C แตไดหยุดการพัฒนาตั้งแตป 2012 หลังจากออก Mac OS 10.8 VV สิ่งที่จะเรียนรูในบทนี้คือการใช Foundation Framework ซึ่งเปนเฟรมเวิรกพ้ืนฐาน เชนการใชตัวเลข สตริง วันที่ หรือ อาเรย ในการเรียกการใชงานเฟรมเวิรกพ้ืนฐานนี้สามารถทำไดโดยการใช #import <Foundation/Foundation.h> พูดไดวาแทบจะทุกโปรแกรมจะตองรวมไฟลนี้เขาไปดวยเสมอ

Number!ในบทที่ผานมา ถาหากเราตองใชขอมูลแบบตัวเลข เราก็จะประกาศตัวแปรใหเปน int , char , double เปนตน ตัวแปรที่เราได

ประกาศไปทั้งหมดนี้เปนตัวแปรที่เรียกวา Primitive Type ไมใชตัวแปรแบบ Object ถึงตรงนี้อาจจะเกิดคำถามในใจวาแลว

ทำไมตองทำเปนออบเจ็กใหยุงยากดวย ประการแรกก็คือเรากำลังเขียนโปรแกรมเชิงวัตถุ ประการที่สองก็คือออบเจ็กทำใหเรา

สามารถสง message หาได (เรียกใชเมธอดของออบเจ็กไดนั่นเอง) ยกตัวอยางที่พบเห็นงายๆเชน ถาตองการจะเปลี่ยนตัวเลข

ใหเปนตัวอักษร เพ่ือนำไปใชงานอยางอื่น เราตองเขียนโคดเพ่ือแปลงคาจาก int , double , float และอื่นๆใหเปนตัวอักษร ขึ้น

มาเองซึ่งเสียเวลา อยางที่สามก็คือคลาสอื่นๆในกลุมของ Foundation มีการทำงานเก่ียวของกับออบเจ็ก เปนตนวาถาหากจะ

เก็บตัวเลขหลายๆคาใน NSArray เราไมสามารถใชตัวแปรแบบ int , float ได ตองเปนออบเจ็กเทานั้น คลาสแรกของ

Foundation Framwork ที่จะใชกันนั่นก็คือคลาส NSNumber ซึ่งเปนคลาสที่เอาไวใชเก็บคาตัวเลข

Program 9.1

1 // main.m2 // Number3 //4 // Created by Ter on 2/9/13.5 // Copyright (c) 2013 Objective-C Book. All rights reserved.6 //78 #import <Foundation/Foundation.h>910 int main(int argc, const char * argv[])11 {

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

1 ถาไดติดตามขาวในชวงป 2010 - 2012 บริษัท Adobe มีปญหากับ Apple มากเพราะใช Carbon เปนหลัก ทำใหตองเขียนโปรแกรมใหมแทบจะทั้งหมด หรือแมกระทั่งโปรแกรมของ Apple เองอยาง iTune ก็เขียนดวย Carbon ซึ่งกวาจะเปลี่ยนมาใช Cocoa ก็ใชเวลาหลายป

Page 3: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

1213 @autoreleasepool {14 15 NSNumber* charNumber = [[NSNumber alloc] initWithChar:'a'];16 NSNumber* intNumber = [[NSNumber alloc] initWithInt:100];17 NSNumber* integerNumber = [[NSNumber alloc] initWithInteger:200];18 NSNumber* floatNumber = [[NSNumber alloc] initWithInteger:3.214];19 NSNumber* longNumber = [[NSNumber alloc] initWithLong:0x12ADF];20 21 22 NSLog(@"char %@",charNumber);23 NSLog(@"int %@",intNumber);24 NSLog(@"integer %@",integerNumber);25 NSLog(@"float %@",floatNumber);26 NSLog(@"long %@\n",longNumber);27 2829 NSLog(@"char %c",[charNumber charValue]);30 NSLog(@"integer %d",[intNumber intValue]);31 NSLog(@"int %ld",[integerNumber integerValue]);32 NSLog(@"float %f",[floatNumber floatValue]);33 NSLog(@"long %ld",[longNumber longValue]);3435 36 [charNumber release];37 [intNumber release];38 [integerNumber release];39 [floatNumber release];40 [longNumber release];41 42 }43 return 0;44 }

Program 9.1 Output

char 97int 100integer 200float 3long 76511

char ainteger 100int 200float 3.000000long 76511

@autoreleasepoolกอนจะอธิบายโปรแกรม มาดูในสวนโคดที่แปลกตากันสักหนอยนั่นก็คือ @autoreleasepool เมื่ออานชื่อก็พอจะเดาไดวามันก็

คือ Autorelease Pool นั่นเอง โปรแกรมในบทกอนๆที่ผานมาเราไดใช NSAutoreleasePool กันเปนหลักและทุกๆครั้งที่เขียน

โปรแกรมก็ตองประกาศ Autorelease Pool เสมอ ในปจจุบันคอมไพลเลอรรุนใหม จึงไดเพ่ิมความสะดวกใหนักพัฒนาไมตอง

เขียน NSAutoreleasePool กันใหยุงยาก เพียงแตใช @autoreleasepool { } แทน NSAutoreleasePool เทานั้นเอง

กลับมาตอดวยโคดของโปรแกรม 9.1 ไดแสดงการใชงาน NSNumber อยางคราวๆ โปรแกรมขางบนเราไดประกาศออบเจ็ก

ทั้งหมด 5 ตัวดวยกัน และเราก็ไดกำหนดคาเริ่มตนใหกับออบเจ็กแตละตัวตางกันเชน charNumber เปนตัวอักษร ‘a’ และ

floatNumber เปนคา 3.214 ถาสังเกตุบรรทัดที่ 16 กับ 17 16 NSNumber* intNumber = [[NSNumber alloc] initWithInt:100];17 NSNumber* integerNumber = [[NSNumber alloc] initWithInteger:200];

จะเห็นวาเปนคาจำนวนเต็มทั้งคู แตสิ่งที่แตกตางกันคือบรรทัด 16 นั้นจะใช initWithInt โดยรับคาแบบ int สวนบรรทัดที่ 17

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 4: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

เรียกใช initWithInteger โดยรับคาแบบ NSInteger แตอยาเพ่ิงเขาใจผิดคิดวา NSInteger นั้นเปนออบเจ็กเพราะเห็นวาขึ้นตน

ดวย NS เพราะแทจริงแลว NSInteger นั้นเปนเพียง typedef ในภาษา C เทานั้น

V การใช NSInteger มีขอดีคือถาหากเปนระบบ 32 bits คอมไพลเลอรจะแปลง NSInteger ใหเปน 32 bits Integer

สวนคอมพิวเตอร 64 bits ก็จะแปลงใหเปน 64 bits Integer แลวเมื่อไหรควรจะใช int หรือ NSInteger ? คำตอบคือขึ้นอยูกับ

ความจำเปน เชนสมมติวาปจจุบันโปรแกรมเราเขียนเปนแบบ 32 Bits ซึ่งอาจจะตองเก็บคาจำนวนเต็มใหญมากๆ เราจึงคิด

เผื่อวาวันหนึ่งเกิดยายระบบจาก 32 Bits ไปยัง 64 Bits โปรแกรมก็จะสามารถเก็บคาจำนวนเต็มไดเทากับ 64 Bits ซึ่งทำใหได

ใชประสิทธิภาพของระบบไดเต็มที่ อีกกรณีคือตัวแปรแบบ Pointer ในระบบ 32 และ 64 มีขนาดไมเทากัน ดังนั้นเพ่ือความ

มั่นใจไดวาเมื่อยายโคดจากระบบ 32 Bits ไปยัง 64 Bits จะไมเกิดปญหาขนาดของ Pointer ที่ตางกัน อยางไรก็ตามอีกหลาย

กรณีก็ไมมีความจำเปนที่จะใช NSInteger เชนถาเรารูอยูแลววาคาของตัวแปรมีคาในชวงตั้งแต 0 - 250 การใช NSInteger ก็

ไมไดเกิดประโยชนเลย กลับกลายเปนใชตัวแปรที่มีขนาดใหญเกินความจำเปน

V กลับมายังโคดของเราตอเมื่อดูการใชงาน NSLog จะเห็นวาโปรแกรมไดแบงออกเปนสองสวนดวยกัน โดยสวนแรก

จะใช %@ เพ่ือใชในการแสดงออบเจ็ก แตถาตองการจะกำหนดใหแสดงคาในแบบที่ตองการก็ทำไดเชนกัน ยกตัวอยางเชน

บรรทัด 22 และ 29 22 NSLog(@"char %@",charNumber);29 NSLog(@"char %c",[charNumber charValue]);

โคดบรรทัด 22 ใช %@ เปนการแสดงคาของออบเจ็กโดยตรงโปรแกรมจึงแสดงคา 96 ซึ่งเปนคา ASCII Code ของตัวอักษร a สวนโคดบรรทัด 29 เรียก charValue เพ่ือที่จะไดคาที่เปนแบบ char ดังนั้นเราจึงใช %c เพ่ือการแสดงคา char ผลลัพธที่แสดงทางหนาจอจึงเปนตัวอักษร aV การเปรียบเทียบคา NSNumber ไมสามารถทำไดโดยใช == เหมือนอยาง primitive type หากตองการจะเปรียบเทียบคาตองใชเมธอด isEqualToValue: ในการเปรียบเทียบ ดังเชนตัวอยางโคดโปรแกรม 9.2

Program 9.2

1 //2 // main.m3 // Number24 //5 // Created by Ter on 2/10/13.6 // Copyright (c) 2013 Objective-C Book. All rights reserved.7 //89 #import <Foundation/Foundation.h>1011 int main(int argc, const char * argv[])12 {1314 @autoreleasepool {15 16 NSNumber* firstNumber = [NSNumber numberWithInt:90];17 NSNumber* secondNumber = [[NSNumber alloc] initWithFloat:90.0];18 19 if( [firstNumber isEqualToNumber:secondNumber])20 NSLog(@"%@ is equal to %@",firstNumber, secondNumber);21 22 [secondNumber release];23 24 }25 return 0;26 }

Program 9.2 Output

90 is equal to 90

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 5: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

โปรแกรม 9.2 เปนการเปรียบเทียบ NSNumber สองจำนวนซึ่งตัวแรกประกาศเปนแบบจำนวนเต็มมีคาเทากับ 90 สวนตัวที่สองเปนจำนวนทศนิยม 90.0 เมื่อเปรียบเทียบจึงมีคาเทากัน นอกจากนี้แลวการประกาศ NSNumber ก็มีความแตกตางกันเพราะ firstNumber ใช class method ในการประกาศ สวน secondNumber ใช instance method ปกติแลวคลาสทุกคลาสใน Foundation ถามีคลาสนั้นมี class method เพ่ือใชในการประกาศออบเจ็ก ออบเจ็กที่ไดจากจะเปนแบบ autorelease ดังนั้นแลวเราจึงไมตองเรียก release เมื่อสิ้นสุดการใชงานV เมื่อพิจารณา numberWithInt ( class method ) และ initWithInt ( instance method ) ก็จะเห็นวาชื่อของเมธอดทั้งสองมีความคลายกันเปนอยางมาก ถึงเราจะยังไมไดเปดคูมือ Reference ก็สามารถที่จะเดาไดวา ถาตองการจะประกาศ NSNumber ที่เก็บ Unsigned Long ดวยคลาสเมธอด ก็นาจะมีเมธอดที่ชื่อ numberWithUnsignedLong และเมื่อเราเปดดู Reference ก็พบวามีเมธอดนี้อยูดังรูป

เมื่อไดศึกษาเก่ียวกับ Foundation Framework มากชึ้นก็จะพบวาคลาสอื่นๆใน Foundation Framework จะมีการตั้งชื่อ instance method และ class method ที่ออกแบบเปนลักษณะแบบนี้เชนเดียวกัน

StringFoundation Framwork มีคลาสที่เก่ียวของกับสตริงอยูดวยกัน 2 คลาสหลักๆคือ NSString และ NSMutableString จริงๆแลวโปรแกรม Hello World ที่ไดเขียนไปตั้งแตบทแรกนั้น เราไดเริ่มใชสตริงไปแลว แตอยูในรูปแบบของ constance string เชน @”Hello World” เปนตน การประกาศ constance string ในภาษา Objective-C มีความคลายคลึงกับภาษา C เพียงแคเพ่ิมสัญลักษณ @ นำหนาสตริงเทานั้นเอง ถึงจะมีรูปแบบที่คลายกันแตภาษา C สตริงเปนเพียงกลุมของขอมูลแบบ char ที่เรียงตอเทานั้น ตัวอักษรที่แสดงดวย char นี้จะเรียกวา ASCII เนื่องจาก char เก็บคาตางๆไดเพียง 1 byte หรือ 255 คา ทำใหการแสดงตัวอักษรตางๆทำไดจำกัด การแสดงผลภาษาอื่นๆเชนภาษาไทย ตองเขียนโคดขึ้นมาเอง สวนสตริงใน Objective-C เก็บขอมูลในรูปแบบ unichar ซึ่งเปนขอมูลตัวอักษรแบบหลายไบต ทำใหเพียงพอที่จะเก็บอักระของภาษาตางๆไดมากมายเชนภาษาไทย ภาษาจีน หรือภาษาอื่นๆ และสิ่งที่พิเศษเมื่อประกาศ constance string ในภาษา Objective-C จะเปนการประกาศสตริงออบเจ็ก ไมใชเพียงแคกลุมของ unichar

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 6: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Program 9.3

1 //2 // main.m3 // String14 //5 // Created by Ter on 2/10/13.6 // Copyright (c) 2013 Objective-C Book. All rights reserved.7 //89 #import <Foundation/Foundation.h>1011 int main(int argc, const char * argv[])12 {1314 @autoreleasepool {15 16 NSString* hello = [[NSString alloc] initWithString:@"Hello World"];17 NSString* text = @"Objective-C"; 18 NSString* textClassMethod = [NSString stringWithString:text];19 20 NSLog(@"%@ \n%@ \n%@", hello , text , textClassMethod);21 22 [hello release];23 24 }25 return 0;26 }

Program 9.3 Output

Hello WorldObjective-CObjective-C

ตัวอยางโคดโปรแกรม 9.3 แสดงการใชงานคลาส NSString เราไดประกาศ NSString ทั้งหมด 3 ออบเจ็กดวยกัน แตใชวิธีการตางกัน โดย hello เรียกใช initWithString สวน text ประกาศแบบ constance string และตัวสุดทาย textClassMethod เรียกใชคลาสเมธอด stringWithString

Basic String methodsคลาส NSString มีเมธอดพ้ืนตางๆใหใชงานคอนขางจะครบถวน เชน การเปรียบเทียบสตริง การเปลี่ยนตัวเปนพิมพใหญ พิมพเล็ก การหาคาความยาวของสตริง ดังเชนตัวอยาง

Program 9.4

1 #import <Foundation/Foundation.h>23 int main(int argc, const char * argv[])4 {56 @autoreleasepool {7 8 NSNumber* number = [NSNumber numberWithInt:30];9 10 NSString* stringA = @"Hello";11 NSString* stringB = @"World";1213 NSString* stringX;14 NSString* stringY;15 NSString* stringZ;16 NSString* stringW;17 18 NSLog(@"stringA %@",stringA);

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 7: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

19 NSLog(@"stringB %@",stringB);20 21 // Copy String22 stringX = [NSString stringWithString:stringA];23 24 // Is equal25 if( [stringA isEqualToString:stringX])26 NSLog(@"stringA is equal to stringX");27 else28 NSLog(@"stringA is not equal to stringX");29 30 // Compare31 NSComparisonResult compareResult;32 compareResult = [stringA compare:stringB];33 if( compareResult == NSOrderedSame)34 NSLog(@"Same");35 else if( compareResult == NSOrderedAscending)36 NSLog(@"Ascending");37 else38 NSLog(@"Decending");39 40 NSLog(@"%@",[stringA uppercaseString ]);41 NSLog(@"%@",[stringA lowercaseString ]);42 43 // Convert number to string44 stringZ = [number stringValue];45 NSLog(@"stringZ %@",stringZ);46 47 // Length48 NSLog(@"stringA length: %ld",[stringA length]);49 50 // Create new string with format51 stringY = [NSString stringWithFormat:@"%@ %@ %@",stringA ,stringB , number];52 NSLog(@"stringY %@",stringY);53 54 // Concat55 stringW = [stringA stringByAppendingString:stringB];56 NSLog(@"stringW %@",stringW);5758 }59 return 0;60 }

Program 9.4 Output

stringA HellostringB WorldstringA is equal to stringXAscendingHELLOhellostringZ 30stringA length: 5stringY Hello World 30stringW HelloWorld

โปรแกรม 9.4 ไดแสดงถึงการใชงานเมธอดพ้ืนฐานตางๆของสตริง จากโคดของโปรแกรมหากตองการเปรียบเทียบสตริง เราสามารถเลือกใช isEqualToString หรือ compare ก็ได แตในการเปรียบเทียบคาวาเทากันหรือไมการใช isEqualToString จะสะดวกกวา แตถาตองการเปรียบเทียบแบบเรียงลำดับตัวอักษรตองใชเมธอด compare ในการเปรียบเทียบV การแปลงขอมูลตัวเลขเปนตัวอักษรก็มีเมธอดใหใชงาน ดังเชนโคดบรรทัดที่ 44 เปนการแปลง NSNumber ใหเปน NSString โดยเรียกใช stringValue เห็นไดวาการเปลี่ยนตัวเลขเปนตัวหนังสือ หรือตัวหนังสือเปนตัวเลข ทำไดงายมากๆ หรือการเปลี่ยนใหเปนพิมพใหญหรือพิมพเล็กก็ทำไดอยางสะดวก การสรางสตริงใหมโดยกำหนดรูปแบบ ( format string ) ก็ทำไดไมยาก ดังเชนบรรทัดที่ 51 เราไดนำ stringA StringB และ number มาใชสรางสตริงใหม และสวนสุดทายบรรทัดที่ 55 เราไดสรางสตริงใหมจากการนำ stringA มาตอดวย stringB

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 8: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Immutable & Mutable String

ตามที่ไดกลาวไปแลววาสตริงใน Objective-C นั้นจะแบงออกเปน NSString (Immutable) และ NSMutableString (Mutable) คำวา Immutable ก็คือเปลี่ยนแปลงไมได สวน Mutable คือเปลี่ยนแปลงคาได ฉะนั้นแลวโคดที่ไดเขียนไปใน 9.4 ก็เปนการใช สตริงแบบ Immutable หรือเปนสตริงแบบเปลี่ยนแปลงไมไดนั่นเอง เพราะวาเราประกาศเปนคลาส NSString ทั้งหมด แตเมื่อยอยกลับไปดูโคดบรรทัดที่

40 NSLog(@"%@",[stringA uppercaseString ]);

อาจจะเกิดขอสงสัยวา ก็ในเมื่อเราประกาศ NSString ซึ่งเปน Immutable ที่แกไขไมได แลวทำไม stringA ถึงไดเปลี่ยนแปลงขอมูลจาก Hello กลายเปนอักษรพิมพใหญ HELLO ความเปนจริงแลว stringA ไมไดเกิดการเปลี่ยนขอมูลในตัวเอง แตสิ่งเกิดขึ้นก็เมื่อเรียกใช uppercaseString คือ stringA จะไปสรางสตริงใหมที่เปนตัวพิมพใหญ แลวสงสตริงออบเจ็กใหมกลับมาใหดังรูป

Hello HELLO

stringA [stringA uppercaseString]

ดังนั้นเราจึงเห็นผลลัพธที่หนาจอเปนคำวา HELLO นั่นเอง V ใน Foundation Framework มีคลาส NSMutableString เพ่ือสรางสตริงที่สามารถเปลี่ยนแปลงคาในภายหลังได การใชงานพ้ืนฐานของคลาสนี้แทบจะเหมือนกับ NSString ทุกอยาง

Program 9.5

1 #import <Foundation/Foundation.h>23 int main(int argc, const char * argv[])4 {56 @autoreleasepool {7 8 NSMutableString* stringA = [NSMutableString stringWithString:@"Hello"];9 NSLog(@"%@",stringA);10 11 // Set new string12 [stringA setString:@"Objective-C"];13 NSLog(@"%@",stringA);14 15 // Append string16 [stringA appendString:@" is fun !!!"];17 NSLog(@"%@",stringA);18 19 // Replace string20 NSRange fullRange = NSMakeRange(0, [stringA length]);21 [stringA replaceOccurrencesOfString:@"!"22 withString:@"*"23 options:NSLiteralSearch24 range:fullRange];25 NSLog(@"%@",stringA);26 27 // Delete character28 NSRange range = NSMakeRange(3, 7);29 [stringA deleteCharactersInRange:range];30 NSLog(@"%@",stringA);31 32 }33 return 0;34 }

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 9: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Program 9.5 Output

HelloObjective-CObjective-C is fun !!!Objective-C is fun ***ObjC is fun ***

จากโคดของโปรแกรม เราไดประกาศ stringA เปนแบบ NSMutableString และเรียกเมธอด ที่เก่ียวของกับการแกไขสตริงเชน setString เพ่ือใชในการเปลี่ยนสตริงใหม หรือ appendString เพ่ือนำสตริงใหมมาตอทาย สวนโคดตั้งแตบรรทัดที่ 20

20 NSRange fullRange = NSMakeRange(0, [stringA length]);21 [stringA replaceOccurrencesOfString:@"!"22 withString:@"*"23 options:NSLiteralSearch24 range:fullRange];

เปนการแทนสตริง ! ดวย * โดยเริ่มตนที่ 0 โดยกำหนดระยะในการคนหาเทากับจำนวนตัวอักษรทั้งหมดของ stringA พูดงายๆก็คือเริ่มตนตั้งแตตัวแรกไปถึงตัวสุดทาย สวน NSLiteralSearch เปน option ที่กำหนดวาใหหาไปทีละตัวโดยตองตรงกันทั้งหมดหมายความวาตัวอักษรพิมพใหญหรือเล็กจะแตกตางกัน ( ยังมี option อื่นๆอีกเชน NSCaseInsensitiveSearch เพ่ือกำหนดวาตัวพิมพใหญหรือพิมพเล็กมีคาเทากัน ) และสุดทายเรียกใช deleteCharactersInRange เพ่ือลบตัวอักษรโดยเริ่มจากตำแหนง 3 โดยมีขนาดความยาว 7 ตัวอักษร

28 NSRange range = NSMakeRange(3, 7);29 [stringA deleteCharactersInRange:range];

Objective-C is fun ***

ตำแหนง 0 ตำแหนง 3

ในเมื่อ NSMutableString เปลี่ยนแปลงคาไดและใชงานไดเหมือนกับ NSString ทุกอยาง งั้นเราควรจะประกาศใหเปน NSMutableString ทั้งหมดเลยดีกวาไหม ? คำตอบคือ “ไมควร” เพราะ NSString นั้นมีประสิทธิภาพดีกวา NSMutableString และบางกรณีเชน parameter ของเมธอดควรใช NSString เพ่ือปองกันการเปลี่ยนแปลงคาของ parameter จากการทำงานภายในเมธอดโดยไมไดตั้งใจ

Searching Stringคลาส NSString และ NSMutableString ไดเตรียมเมธอดเพ่ือใชในการคนหาสตริง หรือการแยกสตริง (Substring) ในการคนหาสตริงเราสามารถกำหนดรูปแบบการคนหาไดเชนเดียวกับการแทนที่สตริง ดังโคดตัวอยางดานลาง

Program 9.6

1 #import <Foundation/Foundation.h>23 int main(int argc, const char * argv[])4 {56 @autoreleasepool {7

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 10: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

8 NSRange rang;9 NSString* resultText;10 NSString* text = @"String objects represent character strings in Cocoa frameworks.\n"11 "Representing strings as objects allows you to use strings\n"12 "wherever you use other objects\n";13 14 NSLog(@"%@",text);15 16 // Search string17 rang = [text rangeOfString: @"Cocoa"];18 NSLog (@"String is at index %lu",rang.location);1920 rang = [text rangeOfString: @"Cocoa Touch"];21 if( rang.location == NSNotFound )22 NSLog (@"String does not found");23 else24 NSLog (@"String is at index %lu",rang.location);2526 // Substring 27 resultText = [text substringToIndex: 14];28 NSLog (@"First 14 chars of text: %@", resultText);29 30 resultText = [text substringFromIndex: 20];31 NSLog (@"String from index 20 : %@", resultText);32 33 resultText = [text substringWithRange: NSMakeRange (10, 4)];34 NSLog (@"String from index 20-26: %@", resultText);35 36 }37 return 0;38 }

Program 9.6 Output

String objects represent character strings in Cocoa frameworks.Representing strings as objects allows you to use stringswherever you use other objects

String is at index 46String does not foundFirst 14 chars of text: String objectsString from index 20 : sent character strings in Cocoa frameworks.Representing strings as objects allows you to use stringswherever you use other objectsString from index 20-26: ects

การกำหนดคาเริ่มตนใหกับสตริงในกรณีที่สตริงยาวมากๆ เราสามารถตัดแบงบรรทัด ไดดังเชนการประกาศ text (บรรทัดที่ 10-12) จากโคดตัวอยาง โปรแกรมไดแสดงการหาสตริงที่ตองการโดยการเรียกใชเมธอด rangeOfString

20 rang = [text rangeOfString: @"Cocoa Touch"];21 if( rang.location == NSNotFound )22 NSLog (@"String does not found");23 else24 NSLog (@"String is at index %lu",rang.location);

ถาโปรแกรมคนหาสตริงที่เราตองการเจอก็จะได NSRang กลับมาซึ่งเปน data structure ที่ประกอบไปดวย location และ lenght เราสามารถใช rang.location แสดงตำแหนงนั้นได แตถาหากไมเจอคา location จะเปนคา NSNotFound

Display data via NSLogคลาสของ Foundation ตางๆ สามารถใช %@ ผาน NSLog เพ่ือแสดงคาของออบเจ็กนั้นไดทุกๆคลาส เชน NSNumber หรือ NSString ทั้งสองคลานี้ใช %@ เหมือนกัน เราก็สามารถที่จะเขียนคลาสขึ้นมาใหมและใช %@ ไดเชนเดียวกันกับคลาสใน Foundation วิธีการคือเราจะทำการ Overriding Method ที่ชื่อวา

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 11: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

- (NSString *)description;

เราจะเขียนโปรแกรมขึ้นมาใหมโดยประกาศคลาสชื่อ Product

Program 9.7

1 // Product.h23 #import <Foundation/Foundation.h>45 @interface Product : NSObject6 {7 NSMutableString* _name;8 float _price;9 }1011 -(void) setName:(NSString*) name andPrice:(float) price;1213 @end

คลาส Product ที่เราไดประกาศขึ้นมานี้ประกอบไปดวย class member อยูดวยกัน 2 ตัวคือ _name ที่ประกาศเปน NSMutableString และ _price เปน float หลังจากนั้นก็ประกาศเมธอดเพ่ือใชในการกำหนดคาใหกับตัวแปรของคลาส เมื่อเสร็จสิ้นจากการประกาศคลาสแลว สิ่งที่ตองทำตอไปคือ การเขียนสวนของ implement ซึ่งมีโคดดังนี้

1 // Product.m23 #import "Product.h"45 @implementation Product6 -(id) init7 {8 self = [super init];9 if( self != nil)10 {11 _name = [[NSMutableString alloc] init];12 _price = 0;13 }14 return self;15 }16 -(void) setName:(NSString*) name andPrice:(float) price17 {18 [_name setString:name];19 _price = price;20 }2122 -(NSString*) description23 {24 return [NSString stringWithFormat:@"%@ %.2f",_name,_price ];25 }2627 -(void) dealloc28 {29 [_name release];30 [super dealloc];31 }32 @end

โคดของเมธอด init ไดจองหนวยความจำใหกับตัวแปรตางๆภายในคลาส และในสวนของเมธอด setName:andPrice ที่ใชในการกำหนดคาของตัวแปร สังเกตุวาเราใช NSString เพ่ือปองกันการเปลี่ยนคาของพารามีเตอรที่รับเขามา และมาถึงสวนที่สำคัญของโปรแกรม

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 12: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

22 -(NSString*) description23 {24 return [NSString stringWithFormat:@"%@ %.2f",_name,_price ];25 }

โคดสวนนี้เราได override เมธอด description โดยสงคาสตริงที่เรากำหนดขึ้นมาใหม กลับไปยังคนที่เรียกเมธอดนี้ ที่เหลือก็คือเขียนโคดสวนการทำงานของโปรแกรมหลัก

1 #import <Foundation/Foundation.h>2 #import "Product.h"34 int main(int argc, const char * argv[])5 {67 @autoreleasepool {8 9 Product* pinkFurby = [[Product alloc] init];10 Product* redFurby = [[Product alloc] init];11 12 [pinkFurby setName:@"Pink Furby" andPrice:2900];13 [redFurby setName:@"Red Furby" andPrice:3000];1415 NSLog(@"%@\n%@",pinkFurby , redFurby);16 17 [pinkFurby release];18 [redFurby release];19 20 }21 return 0;22 }

เพียงเทานี้เราก็สามารถใช %@ เหมือนอยาง Foundation ไดและเมื่อทำงานโปรแกรมก็จะแสดงผลออกมาดังนี้Program 9.7 Output Pink Furby 2900.00Red Furby 3000.00

Autorelease object & initโปรแกรมของเราทำงานไดเสร็จสมบูรณเรียบรอยแลว แตเราจะทำการปรับปรุงคลาสของเราใหใชงานไดงายขึ้นเหมือนกับคลาสของ Foundation โดยที่เราจะเพ่ิมการกำหนดคาตั้งตนใหกับคลาสตั้งแตตอนประกาศตัวแปร และเพ่ิมคลาสเมธอดเพ่ือใชสรางออบเจกเชนกันกับ Foundation ใหเพ่ิมโคดในสวนของ interface ดวยโคดขางลางนี้

+(Product*) productWithName:(NSString*)name andPrice:(float)price;-(id) initWithName:(NSString*)name andPrice:(float) price;

ในสวนของ implementation โคดจะมีหนาตาดังนี้

-(id) initWithName:(NSString*)name andPrice:(float) price{ self = [super init]; if( self != nil) { _name = [[NSMutableString alloc] initWithString:name]; _price = price; } return self;}

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 13: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

+(Product*) productWithName:(NSString*)name andPrice:(float)price{ return [[[Product alloc] initWithName:name andPrice:price] autorelease];}

สิ่งที่ไดเขียนเพ่ิมเขาไปคือ initWithName: andPrice เพ่ือใหคลาสสามารถสรางออบเจ็กและกำหนดคาเริ่มตนไดตั้งแตตอนสราง ทำใหคลาสของเราใชงานไดสะดวกมากขึ้น และย่ิงไปกวานั้นเราไดเพ่ิมคลาสเมธอดเพ่ือสราง instance ของ product ซึ่งชวยอำนวยความสะดวกในกรณีที่ตองการจะสราง autorelase object อีกดวย ดูตัวอยางการใชงานในโปรแกรม 9.8

Program 9.8

1 #import <Foundation/Foundation.h>2 #import "Product.h"34 int main(int argc, const char * argv[])5 {6 7 @autoreleasepool {8 9 Product* pinkFurby = [[Product alloc] init];10 [pinkFurby setName:@"Pink Furby" andPrice:2900];1112 Product* redFurby = [[Product alloc] initWithName:@"Red Furby" andPrice:3000];13 Product* greenFurby = [Product productWithName:@"Green Furby" andPrice:3200];14 15 NSLog(@"%@\n%@\n%@",pinkFurby , redFurby,greenFurby);16 17 [pinkFurby release];18 [redFurby release];19 20 }21 return 0;22 }

Program 9.8 Output

Pink Furby 2900.00Red Furby 3000.00Green Furby 3200.00

ออบเจก pinkFurby ใชเมธอด setName:andPrice ดั้งเดิมที่เราไดเขียนกันไปกอนหนานี้ สวน redFurby ไดกำหนดคาใหตั้งแตตอนประกาศดวยการเรียก initWithName:andPrice และสวนสุดทายเราไดสราง greenFurby โดยการใชคลาสเมธอด productWithName: แมออบเจกทั้งสามนี้ทำงานไดเหมือนกัน แตแตกตางกันในการเรียกเมธอดเพ่ือสรางและออบเจ็กที่ไดก็แตกตางกันในเรื่องของคืนหนวยความจำแบบ autorelease

Read string from & Write String to fileคลาส NSString มีเมธอดที่ใชในการอานและเขียนไฟล อยางงายอยูแลว (คลาสที่เก่ียวของกับการใชไฟลโดยตรงจะอธิบายในบทหลังๆ) เชน

+ (id)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;

เราสามารถใชเมธอดเหลานี้เพ่ืออานและเขียนไฟลได ดังโปรแกรมตัวอยางตอไปนี้

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 14: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Program 9.9

1 #import <Foundation/Foundation.h>23 int main(int argc, const char * argv[])4 {56 @autoreleasepool {7 8 NSString* text = @"String objects represent character strings in Cocoa frameworks.\n"9 "Representing strings as objects allows you to use strings\n"10 "wherever you use other objects\n";11 12 NSError *error;13 NSMutableString* path = [NSMutableString string];14 [path setString:[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]];15 [path appendString:@"/program_data.txt"];16 17 [text writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error ];18 if( error == nil)19 {20 NSString* strFromFile = [NSString stringWithContentsOfFile:path21 encoding:NSUTF8StringEncoding22 error:&error];23 NSLog(@"%@",strFromFile);24 }25 26 }27 return 0;28 }

Program 9.9

String objects represent character strings in Cocoa frameworks.Representing strings as objects allows you to use stringswherever you use other objects

การทำงานของโปรแกรม 9.9 โดยคราวๆ คือเราไดประกาศสตริง และโปรแกรมเรียกใชฟงชั่น NSHomeDirectory() โดยจะไดคาที่เปน Path ของ Home User เมื่อได Home User path แลวตอไปก็เพ่ือกำหนดที่อยูของไฟลที่ตองจะเขียนไปยัง Desktop และใหไฟลมีชื่อวา program_data.txt หลังจากำหนด path เรียบรอยก็เขียนไฟลดวยคำสั่ง

17 [text writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error ];

ไฟลที่เขียนไปเราไดกำหนดให encode ดวย UTF8 และการกำหนดใหเปน atomically หมายถึงวาโปรแกรมจะเขียนไฟลไปยังตำแหนงไฟลชั่วคราวที่ระบบไดสรางขึ้น (auxiliary file) เมื่อเขียนเสร็จเรียบรอยถาไมมีขอผิดพลาดใดๆ โปรแกรมจะคัดลอกไปยังตำแหนงที่เราไดระบุไว แตในกรณีที่เกิดขอผิดพลาดเปนตนวาฮารดดิสเต็มกอนที่จะเขียนเสร็จ ไฟลจะไมไดถูกคัดลอกไปยังตำแหนงที่กำหนด (ถาไฟลอยูแลวจะถูกเขียนทับ) หลังจากที่โปรแกรมไดเขียนไฟลเสร็จเรียบรอยแลว โปรแกรมก็จะอานไฟลที่เพ่ิงเขียนไปและแสดงขอมูล

NSScaner โปรแกรมที่ผานๆมาเราไดใชเมธอดของคลาส NSString เพ่ือใชคนหาตำแหนงของขอความที่ตองการ แตก็เปนเพียงแค

การหาตำแหนงแบบงายๆ ในการหาตำแหนงของขอมูลแบบละเอียด Foundation Framework ไดมีคลาสที่ชวยคนหาขอมูลที่ตองการไวใหอยูแลวนั่นก็คือ NSScaner

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 15: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

โปรแกรมที่จะไดเขียนตอไปคือ XML Parser อยางงาย เพ่ือทดลองการใช NSScaner แตกอนจะลงมือเขียนโคดใหสรางโปรเจคขึ้นมาใหม และเมื่อสรางโปรเจคเสร็จแลวให เพ่ิมไฟล data.txt เขาไปยังโปรเจคของเราจากเมนู New File แลวเลือก Empty File ดังรูป

เมื่อสรางไฟลใหมเรียบรอย แลวใหไปที่ Build Phases ดังรูป

และกดที่ปุมดานขวามือสุด Add Build Phase แลวเลือก Add copy file เมื่อเสร็จแลว จะเห็นแถบบารสีเทาเพ่ิมขึ้นมาวา Copy Files ( 0 item) ใหกดที่รูปสามเหลี่ยมดานซาย และเลือก + จะเจอหนาตางใหเลือกไฟล ใหเลือก data.txt แลวตั้ง Destination ใหเปน Resources เสร็จแลวจะไดดังรูป

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 16: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

ที่เราไดทำไปทั้งหมดคือ เราไดสรางไฟลขึ้นมาใหมเพ่ือเปนขอมูลของโปรแกรม แลวหลังจากนั้นเราก็เพ่ิมขั้นตอนในการ Build ไปอีก 1 ขั้นตอน นั่นก็คือการคัดลอกไฟล data.txt ไปไวยังที่เดียวกับโปรแกรม ( excuteable file ) เพ่ือความสะดวกในการเรียกใชงาน เมื่อทำขึ้นตอนเหลานี้เสร็จเรียบรอยตอไปเราจะลงมือเขียนขอมูลในไฟล data.txt ดังนี้

<?xml version="1.0"><product><name>Red Furby</name><price>3400</price></product>

<product><name>Blue Furby</name><price>2700</price></product>

<product><name>Green Furby</name><price>4200</price></product>

เมื่อเขียนขอมูลในไฟล data.txt เรียบรอยแลวตอไปเราจะสรางคลาสชื่อวา Parser

1 //Parser.h23 #import <Foundation/Foundation.h>45 @interface Parser : NSObject6 +(NSString *)getString:(NSString *)string tag:(NSString *)tag location:(int)location;78 @end

คลาส Parser มีเพียงคลาสเมธอดที่รับสตริง และ XML Tag ที่ตองการ พรอมกับตำแหนงที่จะเริ่มคนหา

1 //Parser .m23 #import "Parser.h"45 @implementation Parser67 +(NSString *)getString:(NSString *)string tag:(NSString *)tag location:(int)location8 {9 NSString *ret = nil;10 if( string != nil)11 {

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 17: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

12 NSScanner *scanner = [[NSScanner alloc] initWithString:string];13 [scanner setScanLocation:location];14 [scanner scanUpToString:[NSString stringWithFormat:@"<%@>",tag] intoString:nil];15 [scanner scanString:[NSString stringWithFormat:@"<%@>",tag] intoString:nil];16 [scanner scanUpToString:[NSString stringWithFormat:@"</%@>",tag] intoString:&ret];17 [scanner release];18 }19 return ret;20 }2122 @end

ในสวนของ implementation ไดประกาศ scaner และกำหนดตำแหนงเริ่มตนของการคนหา ( ในกรณีที่ไมไดตั้งคาจะเริ่มที่ 0 ) สมมติวามีขอมูลคือ <?XML> <Name> Furby </name> เมื่อเริ่มทำงานสแกนเนอรจะเริ่มตนที่ตำแหนงที่กำหนด

< ? x m l > < n a m e > F u r b y < / n a m e >

จากนั้นเราก็จะสแกนสตริงที่ตองการดวย scanUpToString

14 [scanner scanUpToString:[NSString stringWithFormat:@"<%@>",tag] intoString:nil];

เมื่อสแกนเนอรเจอสตริงที่ตองการ สแกนเนอรแยกเอาขอมูลในตำแหนงกอนหนา (intoString) มาใหเราดวย (สวนที่ตัวหนังสือเปนสีเทา ) แตในสวนโคดบรรทัดที่ 14 นี้เราไมตองการ intoString จึงกำหนดคาเปน nil เมื่อจบการทำงานบรรทัด 14 สแกนเนอรจะมีตำแหนงดังนี้

< ? x m l > < n a m e > F u r b y < / n a m e >

หลังจากนั้นเราจะใหสแกนเนอรหาขอมูลสวนที่เปน XML Tag ดวยคำสั่ง scanString

15 [scanner scanString:[NSString stringWithFormat:@"<%@>",tag] intoString:nil];

เมื่อคนหาขอมูลเจอสแกนเนอรก็จะขยับไปยังตำแหนงทายของสตริงที่คนหา และเราก็ไมตองการ intoString เชนกัน

< ? x m l > < n a m e > F u r b y < / n a m e >

และสุดทายใหสแกนเนอรหาสวนปดของ tag แตคราวนี้เราตองเก็บเอาคา intoString เพราะเปนคาที่เราตองการไวยัง ret

16 [scanner scanUpToString:[NSString stringWithFormat:@"</%@>",tag] intoString:&ret];

< ? x m l > < n a m e > F u r b y < / n a m e >

เมื่อเขียนสวนเมธอดของคลาสเสร็จ เราก็จะเขียนสวนของโปรแกรมเพ่ือทดสอบการใชงาน

Program 9.10

1 #import <Foundation/Foundation.h>2 #import "Parser.h"34 int main(int argc, const char * argv[])5 {

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 18: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

6 7 @autoreleasepool {8 9 NSError *error;10 NSMutableString* path = [NSMutableString string];11 [path setString:[[NSBundle mainBundle] bundlePath] ];12 [path appendString:@"/data.txt"];13 14 15 NSString* stringFromFile = [NSString stringWithContentsOfFile:path16 encoding:NSUTF8StringEncoding17 error:&error];18 int loc = 0;19 while (loc < stringFromFile.length)20 {21 NSString* item = [Parser getString:stringFromFile tag:@"product" location:loc];22 if( item != nil)23 {24 NSString* name = [Parser getString:item tag:@"name" location:0];25 NSString* price = [Parser getString:item tag:@"price" location:0];26 NSLog(@"%@ %@",name , price);27 }28 else29 break;30 31 loc += item.length + 10 ;32 }33 34 NSLog(@"%@",stringFromFile);35 36 }37 return 0;38 }

เริ่มแรกกำหนด file path เปน [[NSBundle mainBundle] bundlePath] ซึ่งเปนตำแหนงที่โปรแกรมทำงาน (เนื่องจากเราไดให XCode คัดลอกไฟล data.txt ไปยังตำแหนงเดียวกับ execute file ใน Build Phase) และใหโปรแกรมไดเริ่มอานไฟลหลังจากนั้น โปรแกรมจะเริ่มเขาสู while loop โดยการทำงานภายในลูปคือเรากำหนดใหเริ่มสแกนหา tag ชื่อ product ถาหากไมเจอก็ใหหยุดการทำงานของ loop

19 while (loc < stringFromFile.length)20 {21 NSString* item = [Parser getString:stringFromFile tag:@"product" location:loc];22 if( item != nil)23 {

เมื่อเราไดขอมูลภายใน tag product มาแลว ลำดับตอไปคือ ทำการแยกขอมูลยอยภาย โดยคนหา name และ price

24 NSString* name = [Parser getString:item tag:@"name" location:0];25 NSString* price = [Parser getString:item tag:@"price" location:0];26 NSLog(@"%@ %@",name , price);

เมื่อเสร็จการแยกยอยขอมูล เราจะเลื่อนตำแหนงของสแกนเนอรไปยังจุดทายสุดของ tag product ที่เราไดเจอในตอนแรก ( เลข 10 คือคาความยาวของสตริง </product> )

31 loc += item.length + 10 ;

จากนั้นโปรแกรมก็จะวน loop เพ่ือหา product ใหมโดยเริ่มจากตำแหนงลาสุดที่ไดคนหาไป ผลลัพธของโปรแกรมจึงเปนดังนี้

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1

Page 19: Programming in Objective-C - macfeteriamacfeteria.com/wp-content/uploads/2013/02/Objective_C... · 2013-02-16 · Chapter 8! หลังจากที่เราได เริ่มมีพื้นฐานการเขียนโปรแกรมด

Program 9.10 Output

Red Furby 3400Blue Furby 2700Green Furby 4200

บทนี้เราก็ไดเรียนรูเก่ียวกับหัวใจหลักของ Objective-C นั่นก็คือ Foudation Framework และการประยุกตนำไปใช จะเห็นวา คลาสตางๆภายใน Foundation นั้นมีประสิทธิภาพสูงและมีเมธอดตางอำนวยความสะดวกมากมาย ความสนุกของการเขียนโปรแกรมดวย Objective-C เพ่ิงจะเริ่มตนเทานั้นครับ ในบทหนาเราจะยังลุยกันตอกับ Container Class ตางๆเชน NSArray

Copyright macfeteria.com 2013. All Rights Reserved. -- Chapter 8 Version 1