Home > Objective-C > Objective-C Note ภาคต่อ 2

Objective-C Note ภาคต่อ 2

ยังไม่หมดนะครับเรายังมีหัวข้อที่หน้าสนใจและควรรู้เป็นพื้นฐานต่ออีก สำหรับผู้ที่สนใจใฝ่เรียนรู้หรือต้องการนำไปใช้จริงจังกับการพัฒนางาน โปรแกรมใช้บน MAC OS หรือ IOS  ก็ตามนะครับ แล้วแต่ความสะดวก

การจัดการ Memory Management  เพิ่มเติมจากเดิม
การจัดการ memory ของ Objective-C เรียกว่า reference counting สิ่งที่เราต้องทำก็คือติดตาม reference ของเรา และในระหว่าง runtime จะต้องมีการทำ free memory

พูดให้ง่ายก็คือ เราทำการจอง (alloc) memory ให้ object และเก็บค่าไว้ระหว่างใช้งาน (retain) แล้วทำการ คืนกลับ (release) หลังจากเลิกใช้แล้ว ให้ทำทุกการทำ alloc และ retain
หมายความว่า หาก เราทำการ alloc ครั้งหนึ่ง retain ครั้งหนึ่ง เราจะต้องทำการ release ถึง 2 ครั้งตามภาพ

test

ภาพจาก http://www.cocoadevcentral.com/

ที่กล่าวมาเป็นทฤษฎีของ reference counting ในทางปฏิบัติ เรามีเหตุผลในการสร้าง object อยู่ 2 เหตุผลก็คือ
1. เพื่อใช้งานเป็น instance variable
2. ใช้งานภายใน function หรือภายใน method ของ object

โดยมากแล้ว setter ของ instance variable ควรจะทำแค่การ กำจัดค่าเก่า แบบ autorelease และ retain ค่าใหม่ เพื่อความมั่นใจเราควรที่จะทำการ release มันใน dealloc อีกที ด้วย

งานที่ต้องทำจริง ๆ คือการจัดการกับ local references ใน method หรือ function และก็มีกฏเพียงข้อเดียวเท่านั้นก็คือ ถ้าหหากเราสร้าง object ด้วย alloc หรือ copy ให้ทำ release หรือ autorelease ที่ท้าย function แต่ถ้าหากเราสรา้ง object ด้วยวิธีอื่น ๆ ที่ไม่ได้พูดถึง ไม่ต้องทำอะไร

ตัวอย่างนี้ สำหรับกรณีในข้อ 1 (instance variable )

-(void) setTotalAmount:(NSNumber *)input
{
	[totalAmount autorelease];
	totalAmount = [input retain];
}

-(void) dealloc
{
	[totalAmount release];
	[super dealloc];
}

จะเห็นว่าเรามี totalAmount เป็น instance variable และมีการ กำหนดค่าด้วยการ retain เราทำการ release มันอีกครั้ง ใน dealloc ถึงแม้เราจะกำหนด autorelease ให้มันก็ตาม

ตัวอย่างต่อไปก็คือกรณีถัดมาในข้อ 2 การจัดการกับ local reference สิ่งเดียวที่เราต้องทำก็คือ release object ที่ถูกสร้างด้วย alloc

NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
NSNumber*value2 = [NSNumber numberWithFloat:14.78];
 
// only  release value1 , not value2

และตัวอย่างนี้ แสดงให้เห็นการใช้ local reference กำหนดค่าให้กับ instance variable ของ object

NSNumber* value1 = [[NSNumber alloc] initWithFloat:875];
[self setTotal:value1];

NSNumber*value2 =[NSNumber numberWithFloat:14.78];
[self setTotal:value2];

[value1 release];

สังเกตุวิธีการใช้กฏ สำหรับการ จัดการกับ local reference นั้นเหมือนกัน ไม่ต้องใส่ใจว่าเราใช้มันกำหนดค่าให้กับ instance variable หรือไม่ และเราก็ไม่ต้องสนใจว่า setter นั้นมีหน้าตาเป็นอย่างไร

ถ้าเราเข้าใจจุดนี้เราก็จะเข้าใจ 90% ของสิ่งที่ควรรู้ เกี่ยวกับการบริหารจัดการ memory ใน Objective-C จบปะ

Properties
อย่างที่เราได้ทำการ เขียน accessor method ให้กับ caption และ author ก่อนหน้านั้น เราอาจจะสังเกตุได้ว่า code นั้นค่อนข้างตรงไปตรงมาน่าจะสามารถทำให้เป็นรูปแบบที่ generalized ได้
Properties คือคุณลักษณะที่มีอยู่ใน objective-C ที่จะทำให้เราสามารถสร้าง accessor ได้อัติโนมัติ และนอกจากนี้ยังมีประโยชน์ข้างเคียงอืนๆอีก เรารองมาแปลง Photo class ให้ใช้ properties กันดู

ก่อนหน้ามีหน้าตาแบบนี้

#import 
@interface Photo : NSObject {
	NSString* caption;
	NSString* photographer;
}

-(NSString*) caption;
-(NSString*) photographer;

-(void) setCaption:(NSString*) input;
-(void) setPhotographer:(NSString*)input;

@end

ซึ่งเมื่อแปลงแล้วจะได้หน้าตาแบบนี้

#import
@interface Photo : NSObject {
	NSString* caption;
	NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer;

@property คือ directive สำหรับการประกาศ property
“retain” ในเครื่องหมายวงเล็บเป็นการกำหนดว่า setter ต้องเก็บค่า input ไว้ และส่วนที่เหลือของบรรทัดนั้นเป็นการกำหนด ชนิด (type) และ ชื่อของ property;

ต่อไป ลองมาดูว่าหากใช้ @property จะต้องimplement class อย่าไร

#import “Photo.h”

@implementation Photo 

@syncthesize caption;
@syncthesize phtographer;

-(void) dealloc
{
	;
	[photographer release];
	[super dealloc];
}

@end

@synthesize directive จะทำหน้าที่ในการ สร้าง setter และ getter ให้อัตโนมัติ ดังนั้นสิ่งที่เราต้องทำให้ class นี้แค่การ implement dealloc method

สิ่งที่ควรทราบก็คือ accessor จะถูกสร้างขึ้นในกรณีที่มันไม่มีเท่านั้นเราสามารถที่จะ กำหนด @synthesize ให้กับ propertiy ไว้พร้อมกับการ implement setter และ getter ของเราเองได้ ถ้าเราต้องการ หน้าที่ของ compiler คือการเติม ในส่วนที่เราขาดไป ครับ (เป็นทั้งข้อดี และ ข้อเสียนะเนี่ยย)
อย่างไรก็ตาม เรื่องของ property นี้มีรายละเอียดเพิ่มเติมอีกมากครับ ควรจะต้องศษกาาเพิ่มเติมเพื่อการใช้งานที่ดีนะครับ

ถ้าจะให้ดีก็ ว่ากันต่อไปใน คราวหน้านะครับ
ธีระพงษ์ สนธยามาลย์
s.teerapong@gmail.com

Categories: Objective-C Tags:
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: