คำตอบที่ให้มาใช้งานได้ดีและข้อเสนอของฉันเป็นเพียงส่วนเสริมที่หลีกเลี่ยงการเขียนโค้ดสำเร็จรูปมากเกินไป
เพื่อหลีกเลี่ยงการเขียนเมธอด getter และ setter ซ้ำ ๆ สำหรับคุณสมบัติหมวดหมู่คำตอบนี้แนะนำมาโคร นอกจากแมโครเหล่านี้ความสะดวกการใช้งานของคุณสมบัติประเภทดั้งเดิมเช่นหรือint
BOOL
แนวทางดั้งเดิมที่ไม่มีมาโคร
ตามเนื้อผ้าคุณกำหนดคุณสมบัติประเภทเช่น
@interface MyClass (Category)
@property (strong, nonatomic) NSString *text;
@end
จากนั้นคุณต้องใช้เมธอด getter และ setter โดยใช้อ็อบเจกต์ที่เกี่ยวข้องและget selectorเป็นคีย์ ( ดูคำตอบเดิม ):
#import <objc/runtime.h>
@implementation MyClass (Category)
- (NSString *)text{
return objc_getAssociatedObject(self, @selector(text));
}
- (void)setText:(NSString *)text{
objc_setAssociatedObject(self, @selector(text), text, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
แนวทางที่ฉันแนะนำ
ตอนนี้ใช้มาโครคุณจะเขียนแทน:
@implementation MyClass (Category)
CATEGORY_PROPERTY_GET_SET(NSString*, text, setText:)
@end
มาโครถูกกำหนดไว้ดังต่อไปนี้:
#import <objc/runtime.h>
#define CATEGORY_PROPERTY_GET(type, property) - (type) property { return objc_getAssociatedObject(self, @selector(property)); }
#define CATEGORY_PROPERTY_SET(type, property, setter) - (void) setter (type) property { objc_setAssociatedObject(self, @selector(property), property, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
#define CATEGORY_PROPERTY_GET_SET(type, property, setter) CATEGORY_PROPERTY_GET(type, property) CATEGORY_PROPERTY_SET(type, property, setter)
#define CATEGORY_PROPERTY_GET_NSNUMBER_PRIMITIVE(type, property, valueSelector) - (type) property { return [objc_getAssociatedObject(self, @selector(property)) valueSelector]; }
#define CATEGORY_PROPERTY_SET_NSNUMBER_PRIMITIVE(type, property, setter, numberSelector) - (void) setter (type) property { objc_setAssociatedObject(self, @selector(property), [NSNumber numberSelector: property], OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
#define CATEGORY_PROPERTY_GET_UINT(property) CATEGORY_PROPERTY_GET_NSNUMBER_PRIMITIVE(unsigned int, property, unsignedIntValue)
#define CATEGORY_PROPERTY_SET_UINT(property, setter) CATEGORY_PROPERTY_SET_NSNUMBER_PRIMITIVE(unsigned int, property, setter, numberWithUnsignedInt)
#define CATEGORY_PROPERTY_GET_SET_UINT(property, setter) CATEGORY_PROPERTY_GET_UINT(property) CATEGORY_PROPERTY_SET_UINT(property, setter)
มาโคร CATEGORY_PROPERTY_GET_SET
จะเพิ่ม getter และ setter สำหรับคุณสมบัติที่กำหนด คุณสมบัติอ่านอย่างเดียวหรือเขียนอย่างเดียวจะใช้CATEGORY_PROPERTY_GET
และCATEGORY_PROPERTY_SET
มาโครตามลำดับ
ประเภทดึกดำบรรพ์ต้องให้ความสนใจอีกเล็กน้อย
เนื่องจากชนิดดั้งเดิมไม่ใช่วัตถุมาโครข้างต้นจึงมีตัวอย่างสำหรับใช้unsigned int
เป็นประเภทของคุณสมบัติ ทำได้โดยการตัดค่าจำนวนเต็มลงในNSNumber
วัตถุ ดังนั้นการใช้งานจึงคล้ายคลึงกับตัวอย่างก่อนหน้านี้:
@interface ...
@property unsigned int value;
@end
@implementation ...
CATEGORY_PROPERTY_GET_SET_UINT(value, setValue:)
@end
ตามรูปแบบนี้คุณก็สามารถเพิ่มมาโครมากขึ้นในการสนับสนุนsigned int
, BOOL
ฯลฯ ...
ข้อ จำกัด
มาโครทั้งหมดใช้OBJC_ASSOCIATION_RETAIN_NONATOMIC
โดยค่าเริ่มต้น
ขณะนี้IDE เช่นApp Codeไม่รู้จักชื่อของ setter เมื่อทำการ refactor ชื่อคุณสมบัติ คุณจะต้องเปลี่ยนชื่อด้วยตัวเอง