Objective-C Programming Chapter 10 (Part2)

Protocols

ในบางครั้งการกำหนดข้อตกลงร่วมกันระหว่างสิ่งต่างๆเป็นเรื่องจำเป็น ยกตัวอย่างเช่นอุปกรณ์ที่เชื่อมต่อกับคอมพิวเตอร์ได้ต้องเชื่อมต่อผ่าน usb port เป็นต้น ข้อตกลงระหว่างคลาสต่างๆก็เป็นสิ่งจำเป็น เช่นสมมติว่าเราเขียนคลาสเพื่อแสดงข้อมูลแบบกราฟ แต่ต้องการให้คลาสอื่นเป็นผู้ให้ข้อมูลกับกราฟนี้ได้ ดังนั้นเราจึงต้องตั้งข้อตกลงว่าผู้ให้ข้อมูล จะต้องมีเมธอดมาตรฐานอะไรบ้าง เพื่อให้กราฟสามารถติดต่อขอข้อมูลได้ เช่น จำนวนของแท่งกราฟทั้งหมด , สีของกราฟ , ความสูงของกราฟแต่ละแท่ง เป็นต้น
โปรโตคอลในภาษา Objective-C ก็คือการกำหนดเมธอดที่ใช้ติดต่อร่วมกันระหว่างคลาส การประกาศ protocol ทำได้ง่ายมากเพียงแค่ใช้ @protocol และตามด้วยชื่อของ protocol หลังจากนั้นก็ประกาศเมธอดเหมือนที่เคยทำใน interface และปิดท้ายด้วย @end เช่นกันเดียว ดังตัวอย่าง

เมื่อประกาศ protocol แล้ว คลาสที่ต้องการจะร่วมใช้งาน protocol ต้องประกาศว่าคลาสนั้นเข้ากันได้กับโปรโตคอล ( conform protocol ) โดยการเพิ่มด้วยเครื่องหมาย < ตามด้วยชื่อโปรโตคอล และปิดท้ายด้วย >

ในกรณีที่ต้องการให้คลาสรองรับหลายโปรโตคอลสามารถใช้เครื่องหมาย , คั่นระหว่างชื่อ ได้ดังเช่นตัวอย่าง

หลังจากประกาศว่าคลาสเข้ากันกับโปรโตคอลแล้วก็ต้องเขียน implementation เมธอดของโปรโตคอลนั้นด้วย

เราจะพบเห็นการประกาศโปรโตคอลใน Foundation Framework หลายๆคลาส โดยเฉพาะเมื่อต้องเขียนโปรแกรมด้วย iOS ยกตัวอย่างโปรโตคอลที่ใช้บ่อยๆก็เช่น NSCoding ซึ่งเป็นคลาสที่ใช้ในการแปลงออบเจ็กต์ให้เป็นข้อมูลรูปแบบอื่น (เราจะได้ใช้ NSCoding อย่างละเอียดในบทที่เกี่ยวกับ File และ Archiving) โปรโตคอล NSCoding ได้ประกาศไว้ใน NSObject.h ถ้าหากเปิดดูจะเห็นการประกาศโปรโตคอล NSCoding ดังนี้

สิ่งที่โปรโตคอลได้กำหนดคือเมธอด initWithCoder: และ encodeWithCoder: หมายความว่าหากเราจะประกาศคลาสที่เข้ากันได้หรือรองรับโปรโตคอลนี้ คลาสที่เราประกาศนั้นจำเป็นต้องเขียน implementation ของทั้งสองเมธอด (หากไม่เขียนก็สามารถคอมไพล์ผ่านได้ แต่ XCode จะแจ้ง warning เตือน) Continue reading Objective-C Programming Chapter 10 (Part2)

Objective-C Programming Chapter 10 (Part 1)

Category ,Protocol , Delegate

 

ในการพัฒนาโปรแกรมเราเริ่มจากการออกแบบคลาสและลงมือเขียนโค้ด จากนั้นก็เพิ่มเติมเมธอดให้กับคลาส ขยายความสามารถออกไปเรื่อยๆ ดังเช่นคลาส Product ในบทที่ผ่านมา ในช่วงแรกอาจจะมีแค่เมธอด setter/getter หลังจากนั้นเราก็ขยายความสามารถด้วยการเพิ่มเมธอดต่างๆเข้าไป เช่น เมธอดแสดงราคาที่รวมภาษีมูลค่าเพิ่มเข้าไปแล้ว เป็นต้น ในกรณีแบบนี้ การแก้ไขโค้ดเพิ่มเติมไม่ใช่ปัญหาใหญ่สำหรับเรา เพราะว่าเราเป็นคนเขียนคลาส Product ขึ้นมาเอง
สมมติว่าเราอยากจะเขียนโค้ดเพิ่มเติมให้กับคลาส NSMutableString เช่นมีเมธอดในการสลับตัวอักษรแบบกลับด้าน จะเห็นว่ากรณีแบบนี้เกิดปัญหาขึ้นมาทันที เนื่องจากเราเข้าไปแก้ไขโค้ดของ NSMutableString ไม่ได้ เพราะว่าสิ่งที่ Framework ให้เรามามีแค่ interface (header) และ source code ที่ผ่านการคอมไพล์กลายเป็นไฟล์ไบนารี่แล้วเท่านั้น ดังนั้นหากจะแก้ไขคลาส NSMutableString เราก็เพียงแค่ขอ source code จาก Apple เท่าน้ันเอง แต่วิธีนี้คงเป็นไปไม่ได้แน่นอน วิธีการแก้ปัญหาที่พอจะเป็นไปได้ก็คือสร้างคลาสใหม่โดยการ subclass จาก NSMutableString แล้วเขียนเมธอดที่ต้องการเข้าไปใหม่ก็แก้ปัญหาได้เรียบร้อยแล้ว แต่วิธีการ subclass อาจจะไม่ใช่คำตอบที่ดีที่สุด เพราะสิ่งที่เกิดขึ้นตามมาก็คือคลาสมีขนาดใหญ่ขึ้นเรื่อยๆ เพื่อให้เห็นภาพชัดเจนขอยกตัวอย่างง่ายๆเช่นเป็นต้นว่าคลาส Product ที่เราเคยได้เขียนไป เราสร้างโปรเจคที่สองขึ้นมาใหม่และเขียนเมธอดเกี่ยวกับการจัดการราคาสินค้าเพิ่มเข้าไปทั้งสิ้น 20 เมธอด หลังจากนั้นคลาสนี้ถูกใช้ต่อในโปรเจคที่ 3,4,5 แต่ทั้งสามโปรเจคนี้ไม่ได้ใช้เมธอดที่เพิ่มเติมเข้ามาเลย แต่กลับต้องมีโค้ดทั้ง 20 เมธอดเพิ่มเข้า เพียงเพราะโปรเจคที่สองจำเป็นต้องใช้ ไม่เพียงแค่โปรแกรมมีขนาดใหญ่ขึ้น แต่คลาส Product เองก็มีความซับซ้อนเพิ่มมากขึ้น

Category

นับว่าเป็นข้อได้เปรียบของภาษา Objective-C ที่มีวิธีการเพิ่มความสามารถให้กับคลาสโดยไม่ต้อง sub class ด้วยวิธีการที่เรียกว่าแคทิกอรี่ (Category) วิธีนี้เป็นหนทางที่ช่วยให้เราแก้ไขและเพิ่มเติมเมธอดของคลาสโดยไม่ต้องไปยุ่งเกี่ยวกับโค้ดต้นฉบับเลย การประกาศแคทิกอรี่มีรูปแบบการประกาศดังนี้

ch10_cat_for

เราจะสร้างโปรเจคขึ้นมาใหม่เพื่อทำความเข้าใจกับแคทิกอรี่โดยโปรเจคนี้จะยังใช้คลาส Product จากโปรแกรม 8.7 เมื่อสร้างโปรเจคใหม่และเพิ่มคลาส Product เข้ามาเรียบร้อยแล้ว ต่อไปเราจะสร้าง category โดยการเลือกที่เมนู  New > File หรือจะกดเมาส์ขวาแล้วเลือก New File ก็ได้เช่นกัน จากนั้น XCode จะแสงหน้าต่างให้เลือก template สำหรับการสร้างไฟล์ใหม่ให้เลือก Objective-C category ดังรูป

ch10_cat

Continue reading Objective-C Programming Chapter 10 (Part 1)

Objective-C Programming Chapter 7 (Part 2)

Holding other objects

ที่ผ่านมาเราได้เขียนคลาสที่มีตัวแปร ต่างๆมากมาย แต่ก็เป็นเพียงแค่ตัวแปรแบบธรรมดาทั่วๆไปเช่น ทศนิยม จำนวนเต็ม แต่ในความเป็นจริงแล้ว คลาสต่างๆมักจะมีสามาชิกเป็นออบเจ็กต์ด้วย เราจะสร้างโปรเจคขึ้นมาใหม่โดยใช้คลาสจากโปรแกรม 7.3 ที่ผ่านมาและเพิ่มคลาส harddisk เข้าไปในโปรแกรมของเรา โดยมีโค้ดดังต่อไปนี้

Program 7.4

Harddisk.h

Harddisk.m

และให้แก้ไขโค้ดของคลาส computer ดังนี้

Computer.h

สิ่งที่ได้แก้ไขไปก็คือเพิ่มสมาชิกใหม่ชื่อ externalHarddisk ซึ่งเป็นคลาส Harddisk การประกาศ externalHarddisk จะเห็นว่าเป็นตัวแปรแบบ Harddisk* หรือ pointer นั่นเอง นอกจากนี้เพิ่มเมธอด setExternalHarddisk โดยรับพารามิเตอร์ pointer เข้ามาเช่นกัน Continue reading Objective-C Programming Chapter 7 (Part 2)

Objective-C Programming Chapter 7 (Part 1)

More on classes & Property

ที่ผ่านมาเราได้ลงมือเขียนคลาสเบื้องต้นและทำความเข้าใจเกี่ยวกับหน่วยความจำกันไปบ้างแล้ว ในบทนี้เราจะได้นำความรู้ต่างๆของบทที่แล้วมาใช้และเรียนรู้เกี่ยวกับคุณสมบัติต่างๆของคลาสเพิ่มเติม หากยังไม่เข้าใจเนื้อหาในบทก่อนๆ แนะนำว่าควรจะกลับไปทบทวนและทำความเข้าใจกันอีกสักรอบ เพราะเป็นพื้นฐานที่สำคัญมาก

The id type

แต่ก่อนอื่นจะขอแนะนำตัวแปรแบบใหม่ที่เคยได้เคยเกริ่นไว้ตั้งแต่ช่วงแรกแล้วว่า เป็นตัวแปรแบบชนิดพิเศษ นั่นก็คือตัวแปร id เราเรียกตัวแปรชนิดนี้ว่าเป็นตัวแปรแบบ dynamic typing ตัวแปรที่ผ่านๆมาไม่ว่าจะเป็น int , float หรือ char ล้วนแล้วแต่เป็นแบบ static typing ทั้งสิ้นกล่าวคือเมื่อประกาศตัวแปรชนิดนั้นแล้วจะไม่สามารถเปลี่ยนเป็นชนิดอื่นได้อื่น แต่ตัวแปรแบบ dynamic typing จะต่างออกไป เพราะความพิเศษของมันอยู่ตรงที่ ตัวแปรชนิดนี้สามารถเปลี่ยนเป็นอ็อบเจกต์ได้ทุกชนิด พูดอีกอย่างก็คือตัวแปรนี้ใช้แทนอ็อบเจกต์ใดๆก็ได้ ลองดูตัวอย่างโปรแกรมต่อไปนี้

Continue reading Objective-C Programming Chapter 7 (Part 1)

Review – Nifty MiniDrive

คนที่ใช้ Macbook Air อย่างผมจะประสบกับปัญหาอย่างหนึ่งคือ Hard disk ไม่พอใช้ อย่างตอนนี้ผมใช้ Macbook Air ปี 2009 มีฮาร์ดิสแค่ 128 GB ถ้าจะเปลี่ยนฮาร์ดดิสเองก็ทำได้ลำบาก เพราะ hard disk ของ MBA เป็น SSD ที่ออกแบบมาพิเศษ ไปซื้อมาเปลี่ยนเหมือน SSD รุ่นอื่นไม่ได้ และโดยปกติแล้ว Macbook รุ่นใหม่ จะมาพร้อมกับ SD Card Reader เพื่ออำนวยความสะดวกให้กับผู้ใช้ในการโอนถ่ายรูปจากกล้องลงคอมพิวเตอร์ แต่หลายๆคนตั้งแต่ซื้อเครื่องมาไม่ได้ใช้ slot ตรงนี้ หรือใช้งานน้อยมากๆ จึงมีคนเกิด idea ขึ้นมาว่า เราน่าจะเอาช่องว่างๆที่ไม่ได้ใช้ตรงนี้มาทำเป็น external hard disk น่าจะดี ความคิดนี้ผ่านการระดมทุนจาก Kickstarter ภายในชื่อว่า Nifty Mini Drive  ผมให้ทุนช่วยโครงการนี้ และโครงการก็ให้ drive นี้เพื่อเป็นการตอบแทน ( จริงๆมันก็เหมือนการซื้อของนั่นเหละ เค้าจะตัวเลือกให้เราว่าจะให้ทุนเท่าไหร่ แล้วเราจะได้อะไรกลับมา )

จริงๆแล้วผมควรจะได้ drive นี้ตั้งแต่ปลายปีที่แล้ว แต่ก็อย่างว่าครับ มันเป็นโครงการระดมทุน ซึ่งแปลว่าโครงการอาจจะมีการเปลี่ยนแปลงหรือผิดพลาดได้ โครงการนี้ก็เช่นกันเพราะทาง nifty เองเกิดปัญหาด้านการผลิตและคุณภาพสินค้าตัวอย่างพอสมควร จึงเสียเวลาไปกับการแก้ไข drive พอควร ทำให้ผมเพิ่งจะได้รับ drive มาเมื่อวันก่อน

แกะกล่อง Nifty Drive

nifty_1

เมื่อเปิดพัสดุก็จะพบกับ Packaging ที่เป็นกล่องกระดาษ ที่ผมสั่งไปเป็นรุ่นสำหรับ Macbook Air สีเงิน ( มีทั้งรุ่น Pro , Retina , และ สำหรับ iMac ด้วย และมีหลายสี ) ต้องบอกว่า packaging ทำค่อนข้างดีครับ ดีกว่าที่ผมคิดไว้ ส่วนด้านหลังก็เป็นแบบนี้

nifty_2

Nifty miniDrive นี้มาพร้อมกับเหล็กที่ใช้เกี่ยวสำหรับการถอด drive หลังจากนั้นก็แกะออกมาดู

nifty_3

nifty_4 Continue reading Review – Nifty MiniDrive