سؤال حول STERTER في الهدف
-
16-09-2019 - |
سؤال
هذا مثال من لغة البرمجة الهدف-C 2.0. كنت أتساءل فقط، في الفضل في الأسفل، هل يمكنني استخدام value = [newValue retain]
بدلا من value = [newValue copy]
?
@interface MyClass : NSObject
{
NSString *value;
}
@property(copy, readwrite) NSString *value;
@end
// assume using garbage collection
@implementation MyClass
@dynamic value;
- (NSString *)value {
return value;
}
- (void)setValue:(NSString *)newValue {
if (newValue != value) {
value = [newValue copy];
}
}
@end
المحلول
سيكون أسرع وأكثر أمانا للقيام به هو إضافة @synthesize value
إلى أعلى تطبيقك، وسيقوم المحول البرمجي تلقائيا بإنشاء هذه الأساليب.
مسألة النسخ مقابل الاحتفاظ بالفصلات على حقيقة أنه قد يتم تمريرك في NSMutablestring، مما يؤدي إلى تغيير قيمته. إذا كان لديك قاعدة صارمة لنوع "غير قابل للتغيير" (سلسلة، مجموعة، صفيف، قاموس، قاموس)، تحتاج إلى استخدام copy
دلالات. في البداية، قد يبدو هذا مضادا (لماذا اصنع نسخة إذا كان ثابتا إذا كان ثابتا؟) ولكن الشيء الذي يدركه هو أن صفك يريد أن يفترض أنه غير قابل للتغيير، وما الذي تم تمريره قد لا يكون ثابتا في الواقع.
فئات nsmutable تنفذ copy
محدد عن طريق إرجاع نسخة ثابتة من ما يمثلونه. فئات ثابتة (NSSTRING، إلخ) تنفيذ copy
مع retain
يتصل. هذا هو القول، فهي سريعة جدا.
يحتاج STERTER الخاص بك أيضا إلى الإفراج value
قبل تعيينها قيمة جديدة. الرمز المناسب هو:
-(void)setValue:(NSString*)newvalue
{
if (value != newvalue)
{
[value release];
value = [newvalue copy];
}
}
إذا كان لديك سيطرة كاملة على جميع الفئات التي قد تتصل setValue:
وبالتأكد تماما أنك لن تمر في NSMutablestring، يمكنك استخدام retain
, ، ولكن من الأفضل استخدام الممارسات copy
.
نصائح أخرى
هذا يعتمد. كما ترى [newValue retain]
, ، قد يغير كائن آخر قيمة هذا NSString
مؤشر. عادة، لا ترغب في الحصول على هذا السلوك.
لا، يقول واجهتك copy
. وبعد إذا تم تمرير شخص ما في nsmutablestring، فستحصل على نتائج مختلفة جدا من الطريقتين.
طريقة setter:
-(void)setValue:(NSString*)newvalue{
if (_value != newvalue)
{
[_value release];
_value = nil;
_value = [newvalue copy];
}
}