Verilen cevap harika çalışıyor ve benim önerim çok fazla standart kod yazmaktan kaçınan sadece bir uzantısı.
Kategori özellikleri için tekrar tekrar alıcı ve ayarlayıcı yöntemleri yazmaktan kaçınmak için bu cevap makroları tanıtmaktadır. Ayrıca bu makrolar, int
veya gibi ilkel tür özelliklerinin kullanımını kolaylaştırır BOOL
.
Makro içermeyen geleneksel yaklaşım
Geleneksel olarak aşağıdaki gibi bir kategori özelliği tanımlarsınız
@interface MyClass (Category)
@property (strong, nonatomic) NSString *text;
@end
Ardından, ilişkili bir nesneyi ve anahtar olarak alma seçiciyi kullanarak bir alıcı ve ayarlayıcı yöntemi uygulamanız gerekir ( orijinal yanıta bakın ):
#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
Benim önerdiğim yaklaşım
Şimdi, bunun yerine bir makro kullanarak yazacaksınız:
@implementation MyClass (Category)
CATEGORY_PROPERTY_GET_SET(NSString*, text, setText:)
@end
Makrolar şu şekilde tanımlanır:
#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)
Makro CATEGORY_PROPERTY_GET_SET
, verilen özellik için bir alıcı ve ayarlayıcı ekler. Salt okunur veya salt yazılır özellikler sırasıyla CATEGORY_PROPERTY_GET
ve CATEGORY_PROPERTY_SET
makroyu kullanır .
İlkel türlerin biraz daha dikkat edilmesi gerekiyor
İlkel türler nesne olmadığından, yukarıdaki makrolar unsigned int
özelliğin türü olarak kullanmak için bir örnek içerir . Bunu tamsayı değerini bir NSNumber
nesneye sararak yapar . Dolayısıyla kullanımı önceki örneğe benzer:
@interface ...
@property unsigned int value;
@end
@implementation ...
CATEGORY_PROPERTY_GET_SET_UINT(value, setValue:)
@end
Bu kalıbı takip ederek signed int
, destek BOOL
vb. İçin daha fazla makro ekleyebilirsiniz .
Sınırlamalar
Tüm makrolar OBJC_ASSOCIATION_RETAIN_NONATOMIC
varsayılan olarak kullanıyor .
Uygulama Kodu gibi IDE'ler, mülkün adını yeniden düzenlerken şu anda ayarlayıcının adını tanımıyor. Kendi başınıza yeniden adlandırmanız gerekir.