หลังจากที่เขียน Objective-C ไปแล้วอันแรก ผมคิดว่าถ้าจะเริ่มตั้งแต่ ชนิดของตัวแปร Loop , if-else ก็คิดว่าคงจะใช้เวลาไปหน่อย กว่าจะเขียนเสร็จ ( คือถ้าจะเอาให้ละเอียดเนี่ยสงสัยว่าเขียน หนังสือเลยอาจจะดีกว่า ) เอาเป็นว่า จากนี้ผมขอคิดว่า คนที่อ่านบทความของผม นั้น มีความรู้เกี่ยวกับ C/C++ มาบ้าง ซึ่งสิ่งที่คุณต้องรู้มาก่อนก็คือ
- Data type
ก็จำพวกว่า สามารถประกาศ int , char , array ได้ประมาณนี้ก็พอ - Expression
เป็นต้นว่า เข้าใจการใช้งาน if – else , neatest if-else อะไรทำนองนี้ - Function
ใช้งานฟังชั่นในเบื้องต้นเป็น รวมทั้งความเข้าใจในการส่ง Parameter และการส่งค่ากลับของ function - Pointer
เข้าใจการทำงานของ pointer และการใช้งานเป็นในระดับหนึ่ง - Basic Memory Management
รู้และเข้าใจการจอง memory และการใช้งาน เป็นต้นว่า malloc , free , delete
คือเพราะว่า โดยภาษา Objective-C นั้น มีการใช้งาน Syntax คล้ายๆกับ ภาษา C และ java ค่อนข้างมาก สำหรับคนที่ไม่เคยเขียน โปรแกรมมาก่อน แนะนำว่า ควรไปศึกษา C/C++ มาก่อน ( ผมว่าจะเขียน เหมือนกันแต่เอาให้ obj-c เสร็จก่อนละกัน )
การเขียน Class
การเขียน class ในภาษา objc นั้นจะแบ่งออกเป็น สามส่วนหลักๆคือ
- interface
- implement
- program
ในภาษา objc นั้น มีรูปแบบการประกาศแบบนี้ครับ
@interface classname: parentClassname { // Data member } function @end
การประกาศ class นั้นจะเริ่มด้วย @interface แล้วก็ตามด้วยชื่อของ classname และสำหรับ :parentClassname นั้นก็เป็นส่วนที่บอกว่า class นี้สืบทอด (inheritance) มาจาก class ไหน ในส่วนของ data member นั้นจะประกาศภายในเครื่องหมาย { และ } ส่วน function จะทำการประกาศ ข้างนอก { } และปิดท้ายด้วย @end
เอาละมาดูตัวอย่าง class แรกของเราเลยละกัน
// book.h @interface Book :NSObject { int book_id; float price; } - (void) printDetail; - (void) setPrice: ( float ) p; - (void) setID: ( int ) id; - (void) setPriceAndID: (float) p:(int) id; - (float) getPrice; @end
เราทำการสร้าง class ขึ้นมาใหม่ ชื่อว่า Book ซึ่งประกอบไปด้วย ข้อมูลสองอย่างคือ book_id และ price โดย class นี้สืบทอดมาจาก NSObject และประกอบด้วย 5 method ( function ) นั่นคือ
- - (void) printDetail ;
สำหรับ method นี้ ได้สั่งค่ากลับเป็นแบบ void ( พูดอีกนัยได้ว่าไม่ต้องส่งค่ากลับ ) - - (void) setPrice: (float) p;
ในส่วนของ setPrice นั้นมีการส่งค่ากลับเป็นแบบ void เหมือนกัน แต่ว่าสิ่งที่ต่างจาก printDetail คือ มีการรับ parameter เข้าไปด้วย โดยรับเข้าไปเป็น int และให้ parameter นี้ชื่อว่า p - - (void) setID: (int) id;
ทำงานเหมือนกับ setPrice แต่เป็นการใส่ค่าให้กับ book_id - - (void) setPriceAndID: (float) p : (int) id;
method นี้จะทำการรับ ค่า parameter เข้ามาสองค่า คือ float กับ int การรับค่า parameter เข้ามาหลายๆค่านั้น จะทำการ แบ่งด้วยเครื่องหมาย : (โคล่อน ) - - (float) getPrice;
ฟังชั่นนี้จะทำการส่งค่า price กลับไปเป็นแบบ float
เพียงเท่านี้ก็เป็นการประกาศ Class แบบง่ายๆเสร็จแล้ว
อาจจะงงว่าทำไมต้อง inherit มาจาก NSObject ด้วย ก็ขออธิบายเพิ่มเติมง่ายๆว่า มันคือ Root ของ class ต่างๆในภาษา objective-c สำหรับคำว่า NS นั้น ย่อมาจาก NextStep (เป็นชื่อของบริษัทเก่าที่ Steve Job เคยตั้ง) NSObject นั้นจะมี function ที่สำคัญอันได้แก่ การจอง memory ( alloc ) ให้กับ object นั้นๆ และการ เลิกการจอง ( dealloc) พูดง่ายว่า การประกาศ class ใหม่นั้นต้องสืบทอดมาจาก class นี้
เมื่อทำการประกาศ class ไปแล้ว เรายังเหลือส่วนที่ต้องเขียน นั่นก็คือ ส่วนของ implementation งั้นมาดูกันเลย
//book.m #import <stdio.h> @implementation Book -(void) printDetail { printf( "book id: %i , price %f", book_id, price ); } -(void) setPrice: (float) p { price = p; } -(void) setID: (int ) id { book_id = id; } -(void) setPriceAndID: (float) p: (int) id { book_id = id; price = p; } -(float) getPrice{ return price; } @end
ก็เป็นว่าเสร็จในส่วนของการ implementation แล้ว เหลือส่วนสุดท้ายนั่นก็คือ program
// main.m #import "book.h" int main( int argc, const char *argv[] ) { // create a new instance Book *scibook; scibook = [Book alloc]; [scibook init]; Book *mathbook = [[Book alloc] init]; // set the values [mathbook setID: 1]; [mathbook setPrice: 3]; [scibook setPriceAndID: 2 : 5]; // print it printf( "The Book detail: \n " ); [mathbook printDetail]; [scibook printDetail]; printf( "\n" ); // free memory [mathbook release]; [scibook release]; return 0; }
Sending Message
สำหรับ ภาษา objective-c นั้นจะทำการเรียก function หรือว่า method ว่าเป็นการส่ง message ไปให้มัน ซึ่งรูปแบบก็คือ
[receiver message];
ซึ่งถ้าเทียบกับภาษา C/C++ ก็จะได้ประมาณว่า
receiver->message();
เหมือนเราต้องการจะให้ receiver นั้นทำอะไร เราก็ต้องบอกให้มันทำให้เรานั่นเอง
ขออธิบายในส่วนของ main program กันก่อนละกัน
Book *scibook; scibook = [Book alloc]; [scibook init];
เราเริ่มประกาศตัวแปร scibook ให้เป็น pointer ของ Book และทำการส่ง message ที่ชื่อว่า alloc ไปให้ Book เพื่อทำการจอง memory แล้วหลังจากการจองแล้ว ก็ยังไม่สามารถใช้ได้เลย ต้องทำการ initialize มันซะก่อน ด้วยการส่ง message บอกให้ init อีกที
ปล. initialize คือการให้ค่าเริ่มต้นสำหรับตัวแปรต่างๆ เพราะว่าในการจอง memory นั้น พื้นที่ที่โดนจองอาจจะมีค่าต่างๆที่หลงเหลือจากโปรแกรม อื่นๆ เราก็ต้องปัดกวาด พื้นที่ตรงนั้นให้มันพร้อม เสียก่อน
สำหรับ บรรทัดต่อมา เป็นการรวมสองบรรทัดเข้าด้วยกันเลย ก็จะได้ว่า
Book *mathbook = [[Book alloc] init];
การทำงานเหมือน กับ scibook เลยแค่ ลดให้มันเหลือ 1 บรรทัด อาจจะมองได้ดังรูปต่อไปนี้

เมื่อเรามี object แล้วก็สามารถเรียกใช้ function โดยการส่ง message ไปให้ object เช่น
[mathbook setID: 1];
จากตัวอย่างเป็นการส่ง message ที่ชื่อว่า setID และส่ง parameter ที่มีค่าเป็น 1 ไปให้ตัวแปรที่ชื่อ mathbook ด้วย
และส่วนสุดท้าย
[mathbook release];
เป็นการส่ง message ที่ชื่อ release เพื่อคืนหน่วยความจำให้กับระบบ เราต้องทำทุกครั้งเมื่อจะจบโปรแกรม เพราะว่าไม่งั้นมันจะไม่รู้ว่าโปรแกรมของเราได้ยกเลิกการใช้งานในพื้นที่ตรงนั้นไปแล้ว
ถ้าลอง compile และ run ก็จะได้ผลลัพธ์แบบนี้ครับ
The Book detail: book id: 1 , price 3.0000 book id: 5 , price 2.0000
ก็ลองๆ โหลด source file ไป compile ดูได้ครับ
Objective-C Programming Part I Source File



alvanzoe says:
@synthesize นี้มันคืออะไรหรอ ครับ Tutorial Cocoa ของ Apple พางง นิดหน่อย
March 1, 2008, 5:58 pmadmin says:
คือเวลาเราประกาศ properties เนี่ยมันจะมี 2 อย่างคือ @synthesize กับ @dynamic แล้ว synthesize มันเหมือนเป็นการบอกว่า ให้ Compiler เขียน code ในส่วนของ get/set น่ะครับ
คือถ้าจะเอา code มาเปรียบเทียบให้เห็นอาจจะเข้าใจง่ายกว่า
@interface MyClass : NSObject
{
NSString *value;
}
@property(copy, readwrite) NSString *value;
@end
// assume using garbage collection
@implementation MyClass
@synthesize value;
@end
ถ้าเป็น dynamic จะได้ว่า
@interface MyClass : NSObject
{
NSString *value;
}
@property(copy, readwrite) NSString *value;
@end
// assume using garbage collection
@implementation MyClass
@dynamic value;
- (NSString *)value {
return value;
}
- (void)setValue:(NSString *)newValue {
if (newValue != value) {
value = [newValue copy];
}
}
@end
ถ้าเราประกาศให้เป็น synthesize จะเห็นว่า code มันสั้นกว่า
เราไม่ต้องไป implement มันเหมือน dynamic หลังจากประกาศ synthesize แล้ว เราก็สามารถใช้ได้เลย
เช่นว่า
MyClass *myInstance = [[MyClass alloc] init];
myInstance.value = @”New value”;
NSLog(@”myInstance value: %@”, myInstance.value);
น่าจะพอเข้าใจน่ะครับ
March 2, 2008, 12:15 pmbiggoogle says:
บรรทัด
- (void) setPrice: (float) p;
ในส่วนของ setPrice นั้นมีการส่งค่ากลับเป็นแบบ void เหมือนกัน แต่ว่าสิ่งที่ต่างจาก printDetail คือ มีการรับ parameter เข้าไปด้วย โดยรับเข้าไปเป็น int และให้ parameter นี้ชื่อว่า p
มันผิดมั๊งครับ
- (void) setPrice: (float) p;
ในส่วนของ setPrice นั้นมีการส่งค่ากลับเป็นแบบ void เหมือนกัน แต่ว่าสิ่งที่ต่างจาก printDetail คือ มีการรับ parameter เข้าไปด้วย โดยรับเข้าไปเป็น float และให้ parameter นี้ชื่อว่า p
ใช่มั๊ยครับ
January 16, 2010, 10:52 amadmin says:
ครับผม ขอบคุณครับ
January 20, 2010, 4:53 pmdeen05 says:
บทความเข้าใจง่ายดีครับ
July 23, 2011, 11:41 amเริ่มรู้สึกว่ามันคล้าย JAVA แล้ว
kantae says:
ถ้าผมลืม release มันจะค้างในหน่วยความจำจนถึงตอนไหน
September 17, 2011, 9:36 pmและสงผลกับโปรแกรมร้ายแรงไหมครับ