Key Value Coding
โดยปกติแล้วเราสามารถใช้ method ที่ชื่อว่า setValue:forKey: เพื่อทำการ set ค่าให้กับ ตัวแปรใน class ได้ดังตัวอย่างข้างล่างนี้
สมมติว่าเรามี Class แบบนี้
@interface Book : NSObject { NSString *name; } @end
เราสามารถที่จะ set ค่าให้กับ name ได้แบบนี้
book = [[Book alloc]init]; [book setValue:@"FHM" forKey:@"name"];
และเราก็สารมารถที่จะ get ค่าจาก name ได้แบบนี้
NSString *bookName = [book valueForKey:@"name"];
ดูแบบนี้อาจจะเหมือนว่ามันไม่ค่อยจะมีประโยชน์มากนัก แต่เราจะได้ใช้ในเรื่องของ Binding ในส่วนต่อไป
Accessor Method
มันก็คือ method ที่เป็นลักษณะ Get – Set นั่นเหละครับ ถ้าหากเรามี class book แบบข้างบน เราอาจจะเขียน accessor method ได้ว่า
-(NSString*) getName { return name; } -(void) setName:(NSString*) n { name = n; }
โดยปกติแล้ว accessor method นั้นจะมี pattern ลักษณะ
-<Key>
-set<Key>
-get<Key>
รายละเอียดเพิ่มเติมของ pattern อ่านได้ที่ http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/AccessorConventions.html#//apple_ref/doc/uid/20002174
คือถ้าหากว่าเราเขียน method ที่มีการทำงานเหมือนกันแต่ว่า มันไม่ตรงกับ pattern ก็ไม่อาจจะเรียกได้ว่าเป็น accessor method เช่นว่า
-(void) setBookName:(NSString*) n { name = n; }
คือเรามองว่าจาก setBookName นั้นประกอบไปด้วย “set” และ “BookName” ซึ่ง BookName ถือว่าเป็น key และใน class book นั้นก็ไม่ได้มี member ที่ชื่อ BookName ดังนั้น method นี้ก็ไม่อาจจะเรียกว่าเป็น acessor method ได้
Binding
binding คือการจับคู่ระหว่าง object กับตัวอ้างอิง และใน cocoa เองก็มีการใช้ binding กับ graphic object มากมาย ยกตัวอย่างเช่นว่า เราอาจจะ binding ค่าของตำแหน่งของ slide กับตัวแปร slidePosition เมื่อเราเลื่อน slide ค่าของ slidePostion ก็เปลี่ยนไปตามตำแหน่งของ slide เป็นต้น
อาจจะมองไม่ค่อยจะเห็นภาพว่าเราจะใช้ Binding ได้ยังไง และจะนำ key-value-coding ไปใช้ได้ยังไง งั้นมาดูตัวอย่างการใช้งานจริงๆกันเลยดีกว่า
สมมติว่าเราต้องการเขียนโปรแกรม นับจำนวนของคำ เหมือนดังตัวอย่างแรกๆ แต่ครั้งนี้เราจะใช้ Binding เข้ามาช่วย
ก่อนอื่นก็สร้าง โปรเจคขึ้นมา แล้วก็ add class ที่ชื่อว่า AppController เหมือนที่ผ่านมาในตัวอย่างก่อนๆ โดยใน AppController ของเราจะมี code ดังนี้
#import @interface AppController : NSObject { IBOutlet NSTextField *m_textFieldInput; IBOutlet NSTextField *m_textFieldCounter; NSString *myText; } - (void) setMyText:(NSString*) text; -(NSString*) getMyText; @end
ก็จะเห็นว่า เราแทบจะไม่มีอะไรเลยนอกจาก NSTextField 2 ตัวและ 2 method และส่วน implement ก็เขียนได้แบบนี้ครับ
@implementation AppController - (void) setMyText:(NSString*) text { if ([text length] != 0 ) { myText = text; [m_textFieldCounter setIntValue:[myText length] ]; } } -(NSString*) getMyText { return myText; } @end
จาก code ข้างบนก็เพียงแค่ setMyText จะไปนับจำนวนของ myText แล้วก็แสดงผลออกมาเท่านั้นเอง
ต่อไปเราก็สร้าง interface ของเราให้มีลักษณะแบบนี้
และเราก็ สร้าง instance ของ App Controller และ link กันเหมือนเดิม ( ดังรูปข้างล่าง )
link ให้ครบทั้ง 2 NSTextField เลย
และที่สำคัญมากๆ เราต้องมา set binding ตรง inspector แบบรูปข้างล่าง
สิ่งที่เราต้องทำก็คือ Bind to: ให้ set เป็น App Controllerและส่วน Model Key Path นั้นเราก็ set ให้เป็น myText เพื่อให้มันตรงกับค่าของ ตัวแปร myText
ลอง Compile & Run ดูครับ แล้วลองพิมพ์ ข้อความลงไป พร้อมกับกด Enter จะเห็นว่า ตรง Label ก็จะเปลี่ยนเป็นจำนวนตัวอักษรที่เราพิมพ์ลงไป
จะเห็นว่า เราแทบไม่ต้องไปเขียนอะไรเพิ่มเติมเลย เพราะมันเอา key ไป bind ให้เราโดยอัตโนมัติ ถ้าหากเรา debug เวลาที่เราพิมพ์และหลังจาก enter มันก็เข้ามายัง method setMyText ดังรูป
และถ้าหากเราดู Call Stack ก็จะเห็นว่า methode ที่ได้เรียก setMyText นั้นจะมาจาก setValue:forkey อีกที
ไม่เข้าใจก็ถามเข้ามาได้ครับ แต่ผมก็รู้สึกได้ว่าเขียนงงๆ ก็เอาเป็นว่ามีคำแนะนำติชม ก็คอมเม้นกันมาครับ









adirak says:
ขอบคุณครับ
July 2, 2009, 10:28 am