Objective-C Tutorial, Properties
גיא שביב |
ספט 22, 2009 במאמר זה אני אדבר על תכונה של ObjectiveC והיא הגדרת properties. תכונה זו נכנסה לשפה בגירסא 2.0 שהיא הגרסא בשימוש כיום בערכת הפיתוח של האייפון ולאופרד.
מי שתכנת בגרסא 1.0 של השפה מכיר את התבנית הבאה להגדרת משתני מופע ופונקציות גישה אליהם:
@interface Person : NSObject {
NSString *name;
int age;
}
- (NSString*) name;
- (void) setName:(NSString*) aName;
- (int) age;
- (void) setAge:(int)anAge;
@end
בדוגמא זו אנו מגדירים כיתה ושני משתני מופע ומגדירים פונקציות גישה אליהם. המומוש של פונקציות הגישה פשוט אך דורש שימת לב לניהול הזכרון המימוש יכול להראות כך:
@implementation Person
- (NSString*) name {
return name;
}
- (void) setName:(NSString*)aName {
[name autorelease]; // *
name = aName;
[name retain]; // *
}
- (int) age {
return age;
}
- (void) setAge:(int) anAge {
age = anAge;
}
@end
שימו לב לשורות המסומנות ב* אשר דואגות לניהול זכרון תקין (עוד על ניהול זכרון במאמר נפרד שנשתדל לפרסם בהקדם).
בגירסא 2.0 של השפה (שכאמור זו הגירסא בשימוש כיום) כל זה נחסך מאיתנו. בגירסא 2.0 ההגדרה של הכיתה תראה כך:
@interface Person : NSObject {
NSString *name;
int age;
}
@property (nonatomic,retain) NSString* name;
@property (assign) int age;
@end
ואילו המימוש יראה כך:
@implementation Person
@synthesize name;
@synthesize age
@end
פשוט יותר, לא?
מה בעצם קרה כאן? בהגדרת הכיתה הגדרנו שקימות פונקציות גישה על ידי השימוש במשפט @property שהמבנה שלו הוא:
@property (<parameters>) <type> <name>;
הסוג שמופיע במשפט תואם את סוג המשתנה (סוג הערך שפונקצית הקריאה תחזיר) והשם תואם את שם המשתנה אליו ניגשים (לא חובה, ניתן גם לבחור שם אחר). הפרמטרים מגדירים את פעולת פונקצית הגישה. פרמטרים נפוצים הם:
- copy מגדיר שהפונקציה תציב למשתנה המופע עותק של הארגומנט.
- retain מגדיר שהפונקציה תציב את ערך הארגומנט ותשמור עליו. רלוונטי רק לסוגי משתנים שיורשים מNSObject.
- assign הפונקציה תציב את ערך הארגומנט ללא ניהול זכרון.
- nonatomic הפונקציה אינה thread safe.
- readonly יש רק פונקציה לקריאה, לא לכתיבה.
המשפט synthesize מורה לקומפיילר לייצר את פונקציות הגישה עבורנו. למעשה הקומפיילר יגדיר לנו פונקציות עם שמות בדומה לתבנית השימוש שהדגמנו עבור גירסא 1.0 של השפה.
גם השימוש בפונקציות הגישה נהיה פשוט יותר. אם בגירסא 1.0 של השפה כתבנו:
[aPerson setName:@"Guy"];
if ([aPerson age] > 100) {
// really old
}
הרי שבגירסא 2.0 של השפה אנחנו יכולים לכתוב אותו הדבר (הקומפיילר כאמור מייצר פונקציות גישה עבורינו) או שאנחנו יכולים להשתמש בתחביר מקוצר:
aPerson.name = @"Guy";
if (aPerson.age > 100) {
// really old
}
ישנם עוד כמה נושאים שלא כיסיתי כמו הגדרה דינמית של פונקציות הגישה' תכלו לקרוא את התחביר המלא של המשפטים @property ו–@synthesize באתר של אפל.

Reader Comments (2)
מאמר נחמד - רק הערה קטנה. class בעברית זה 'מחלקה' ולא כיתה.
ירון,
נכון, למדתי זאת בהמשך, במאמרים מאוחרים יותר כבר השתמשתי בעברית נכונה יותר.