Cocoa Programming IV : More about – Binding & Property

Technology อย่างหนึ่งของ Cocoa ก็คือการ Binding และในวันนี้ผมจะอธิบาย Cocoa Binding รวมถึงตัวอย่างการใช้งาน แบบง่ายๆ กัน

MVC – Model View Controller

โดยปกติแล้วการเขียนโปรแกรมด้วย Cocoa เราจะใช้ MVC ( Model View Controller ) design pattern ในการเขียนโปรแกรมค่อนข้างเยอะมาก อาทิเช่น Bindings , Core Data เป็นต้น เราจะมาทำความเข้าใจกันก่อนว่า MVC คืออะไร

  • Model พูดง่ายๆว่าคือ ข้อมูล อาจจะรวมไปถึงวิธีการเก็บข้อมูลด้วย เช่นเราเขียนโปรแกรมที่ต้องการ เก็บคะแนนวิชาเลขของนักเรียน เราอาจจะมี เขียน Class ขึ้นมาชื่อว่า Student เพื่อเอาไว้เก็บคะแนนและชื่อของนักเรียน
  • View ก็คือส่วนที่เอาไว้ติดต่อผู้ใช้ GUI นั่นเหละครับ ยกตัวอย่างเช่น NSButton เป็นต้น
  • Controller คือส่วนของการควบคุม หรือส่วนกลางระหว่าง ข้อมูลกับ GUI ยกตัวอย่างเช่น อาจจะเป็น Class ที่มี Method ที่เอาไว้ควบคุมการ add / remove รายชื่อนักเรียนเป็นต้น

และในการเขียนโปรแกรมด้วย Cocoa นั้นจะพบว่าเราต้องเขียน Class ในลักษณะ MVC ค่อนข้างเยอะมาก ดังนั้นจึงได้มี Binding เข้ามาเพื่อช่วยให้ลดการเขียน Class จำพวก Controller

Binding

จริงๆแล้วผมได้อธิบายไว้ใน http://www.macfeteria.com/2008/08/cocoa-programming-iii-key-value/ แล้วแต่จะขอยกตัวอย่างง่ายๆอีกสักตัวอย่าง เพื่อให้เข้าใจ Binding กันมากขึ้น โดยครั้งนี้เราจะ Binding ให้เข้ากับ Property ของ Class ที่เราได้เขียนไว้

การ Binding คือการที่เรานำ key (หรือตัวแปร) เชื่อมกับค่า attribute ต่างของ Object ที่เอาไว้แสดงผล เช่นสมมติว่า หน้าตาโปรแกรมดังรูป

interface

เพื่อความเข้าใจ เรามาลองเขียนโปรแกรมทดลองกันเลยดีกว่า โดยเริ่มจาก สร้างโปรเจคขึ้นมา โดยให้ชื่อว่า Binding

หลังจากนั้นเราก็ออกแบบหน้าตาโปรแกรมให้มีลักษณะดังกล่าว ต่อไป เพิ่ม class ที่ชื่อว่า AppController เหมือนที่เราเคยทำมาเช่นเดิม

project

ต่อไปเราก็เขียน Code ของ AppController.h  ดังเช่นข้างล่าง

และส่วน Code ของ AppController.m ก็มีดังนี้

จะเห็นว่าตัวอย่างโปรแกรม ก็ทำงานอย่างง่ายๆคือ มี ตัวแปร ที่ชื่อว่า m_position และมี IBOutlet อีกสองอย่างคือ NSButon กับ NSTextFields เท่านั้นเอง ส่วน code ของ implement นั้นก็มีเพียง Function ทีชื่อว่า GetPosition เท่านั้นและหน้าที่ของฟังก์ชั่นนี้ก็ไม่ได้ทำอะไรมาก นอกจาก set ค่า String เข้าไปยัง m_text แค่นั้นเอง

หลังจากนั้นก็เปิด Interface Builder แล้วก็ add  object ของ AppController เข้ามาดังรูป

appcontroller

ต่อไปคือ การ link NSButton เข้ากับ m_button และ NSTextFields เข้ากับ m_text เข้ากับ interface เหมือนที่เคยทำมา ดังรูป

linkobj

และก็ link Function ที่เราได้เขียนไว้ นั่นคือ GetPostition เข้ากับ Button เหมือนดังรูปภาพข้างล่าง

getposition

ต่อไปส่วนที่สำคัญมาก ก็คือเราจะ Bind ตัวแปร m_position ให้เข้ากับ ตำแหน่งของ slider วิธีการ ก็ไม่ยากครับ ก็คือเราก็กลับไปที่ Interface Builder แล้วก็เปิด Inspector ขึ้นมา จากนั้นก็เลือกไปที่ Slider ที่เราได้ออกแบบไว้ แล้วเลือกไปที่ Binding Inspector ก็จะเห็น หน้าต่างเหมือนดังรูป

binding

สิ่งที่จะต้องทำการ setting ก็คือ ในส่วนของ Value เราก็เลือก Bind To: ไปที่ App Controller แล้ว Model Key Path ของเรา ก็ใส่ m_position ลงไป
จากที่เราทำไป ก็เป็นการบอกว่า เราจะ Bind Value ของ Slider ไปยัง App Controller แล้วใช้ Key ที่ชื่อว่า m_position หลังจากนั้นเราก็ ทำการ compile ครับ

จากโปรแกรม เราก็ลองเลื่อนตำแหน่ง ของ Slider ดูแล้วหลังจากนั้น เราก็ กด Get Position ดูครับ จะเห็นว่า position text จะเปลี่ยนค่าไป เหมือนดังรูป

program_a

จะเห็นว่า เราไม่ต้องไปเขียน Function ใดๆเกี่ยวกับ Slider เลย เพราะเราได้ใช้การ Binding เข้าช่วย ถ้าหากจะพิจารณากันจริงๆแล้ว โปรแกรมทำงานอย่างไร ก็ขออธิบายอย่างง่ายได้ว่า

  • จาก  AppController นั้นจะมีตัวแปร ที่ชื่อ m_position เป็น integer และเราก็ได้กำหนดให้ m_position นี้เป็น properties
  • ดังนั้นแล้ว เราก็เข้าถึง m_position โดยที่ไม่ต้อง เขียน Getter/Setter
  • ต่อไปเราก็ทำการ Binding Slider  โดยใช้ m_position เป็น key ดังนั้นเมื่อเราเลื่อน slider มันจะไปเรียก Setter/Getter ของ m_postion
  • แต่เนื่องจาก m_position ของเราเป็น property เราจึงไม่ต้องเขียน Getter/Setter

ถ้าหากเปรียบโปรแกรม ระหว่าง http://www.macfeteria.com/2008/08/cocoa-programming-iii-key-value/ ที่ได้เคยเขียนไป ก็จะเห็นว่าเราไม่ต้องเขียน Getter/Setter

Key Value Observing

จากโปรแกรม ข้างบน ถ้าหากเรามี method อื่นๆที่ทำการเปลี่ยนแปลงค่าของ m_position โดย method อื่นๆ เช่นสมมติว่าเราเพิ่ม Button ที่ชื่อว่า Increase Position เข้าไปเพื่อเพิ่มค่าของ m_position แล้ว slider จะรู้หรือเปล่า ว่าค่าได้มีการเปลี่ยนแปลง ? คำตอบก็คือ ไม่สามารถรู้ได้ ดังนั้นถ้าหากเราต้องการให้ slider นั้นรู้ว่าได้มีการเปลี่ยนแปลงค่าของ m_position จากส่วนอื่นๆ เราก็จะใช้ Key-Value Observing เข้ามาช่วย

สมมติว่าจาก โปรแกรมข้างบน เราได้เพิ่ม ปุ่มกด Increase Position เข้าไปดังรูป

interface2

และเพิ่ม IBAction method เข้าไปที่ AppController ที่มีชื่อว่า IncreasePosition: และเขียน implement ได้ดังนี้

และเราก็เชื่อม button ของเราให้เข้ากับ IncreasePosition: ใน interface builder ดังรูป

link2

แล้วลอง Compile และ Run ดู หลังจากนั้นก็ลองกด ปุ่ม Increse Position ดูครับ ตามหลักแล้วเมื่อเราเพิ่มค่าของ m_position จากการกดปุ่มที่เราได้เพิ่มเข้าไป slider ก็ควรจะเลื่อนตำแหน่งใช่ไหมครับ เพราะว่าค่าของ m_position ได้เปลี่ยนไป แต่เมื่อเราได้ run ดูจริงๆแล้ว จะเห็นว่า ไม่มีอะไรเกิดขึ้นเลย แต่ความจริงแล้วค่าของ m_position ก็ได้เปลี่ยนไปแล้วนะครับ ถ้าหากเราเปิด Console ขึ้นมาก็จะเห็น Log ว่าค่าของ m_position ได้เปลี่ยนเหมือนดังรูป

result

เอาละ แล้วเราจะทำยังไง ?

สิ่งที่เราต้องเพิ่มเข้าไปก็คือ ต้องทำให้ตัวโปรแกรมและส่วนอื่นๆรู้โดยการใช้ notification วิธีการก็ไม่ยากครับ เราเพียงแค่ เพิ่ม code เข้าไปแบบนี้

เพียงเท่านี้ก็เป็นอันเสร็จ เราลองกด Increase Position ใหม่อีกครั้ง จะเห็นว่า ตำแหน่งของ slider ก็ได้เปลี่ยนไปด้วย หรือเราอาจจะเขียนได้อีกรูปแบบคือ

ก็ใช้งานได้เหมือนกัน เพียงแต่เราได้ใช้ Key Value เข้ามาช่วย และในครั้งหน้าเดี๋ยวเราจะได้ใช้ Binding กับ Array Controller ครับ

2 thoughts on “Cocoa Programming IV : More about – Binding & Property”

  1. มันสร้างขึ้นมาเองครับ เพราะว่า เราได้ประกาศ m_position เป็น property
    ภาษา Objective-C ต้องใช้เครื่องหมาย @ นำหน้าสตริง

  2. พี่ครับ Function setM_position นี้มันสร้างขึ้นมาเองใช่มั้ย
    String ทำไมต้องมี เครื่องหมาย @ ด้วยครับ

Leave a Reply