Objective-c中的自定义属性属性

像VB.NET一样,可以在Objective-C中创build自定义属性属性? 例如,在VB.NET中,您可以创build“Browsable”属性并在运行时读取它,以确定是否显示属性。

Public Class Employee <Browsable(True)> _ Public Property Property1() As String Get End Get Set(ByVal Value As String) End Set End Property <Browsable(False)> _ Public Property Property2() As String Get End Get Set(ByVal Value As String) End Set End Property End Class 

我想在Objective-C中做同样的事,即使它是一个固定的属性,只能在编译时设置,根本不能修改。

我想要做的是添加一个属性到我的类的属性,以确定属性是否应该序列化。

我知道标准的Objective-C属性(只读,非primefaces等),但这些不能帮助我…除非你有创造性的方式来使用它们。 我还研究了使用C属性和__attribute__(("Insert attribute here"))关键字,但是C具有特定的属性来满足特定的目的,我甚至不确定你可以在运行时读取它们。 如果我错过了一个可以帮助我的人,请告诉我。

我试过使用typdef 。 例如:

 typdef int serializableInt; serializableInt myInt; 

并使用property_getAttributes() Objective-C运行时函数,但是它告诉我的是myInt是一个int。 我想在这种情况下typedef非常像一个macros,除非我可以在运行时创build一个serializableInttypes的variables。 无论如何,这里是苹果关于你从property_getAttributes()获得的值的文档 。

另一个要求是这个属性必须和NSObject的子类以及原始数据types一起工作。 我考虑过把黑名单或白名单添加到class级中作为一个伊娃,这会告诉我哪些属性要跳过或序列化,这是基本上相同的想法。 我只是试图将黑/白名单移动到属性中,所以当你看到一个类的头文件时,它很容易理解,它在我创build的任何类中都是一致的,并且不太容易出错。

另外,这是要考虑的事情。 我不需要属性有一个值(TRUE或FALSE; 1,2,3;或其他),因为属性本​​身就是值。 如果该属性存在,则序列化; 否则,跳过。

任何帮助表示赞赏。 如果您确定Objective-C上无法实现,请告诉我。 谢谢。

除非我错过了你的观点

我build议宣布一个协议。 然后在objc类中使用objc对象的实例作为variables,这些objc类使用协议。

 @interface MONProtocol - (BOOL)isSerializable; - (BOOL)isBrowsable; /* ... */ @end @interface MONInteger : NSObject <MONProtocol> { int value; } - (id)initWithInt:(int)anInt; @end @interface MONIntegerWithDynamicProperties : NSObject <MONProtocol> { int value; BOOL isSerializable; BOOL isBrowsable; } - (id)initWithInt:(int)anInt isSerializable:(BOOL)isSerializable isBrowsable:(BOOL)isBrowsable; @end // finally, a usage @interface MONObjectWithProperties : NSObject { MONInteger * ivarOne; MONIntegerWithDynamicProperties * ivarTwo; } @end 

如果你想分享一些实现,那么只需要NSObject的子类并扩展基类。

你会有几个变体来写你想要代表的types/结构。

到目前为止,我所看到的其他答案的不足之处在于它们是作为实例方法实现的,也就是说,在查询元数据之前,您已经有了一个实例。 在适当的情况下可能存在边缘情况,但是类的元数据应该作为类方法来实现,就像苹果一样,例如:

 + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key { } 

我们可以想象我们自己沿着类似的路线:

 + (BOOL)keyIsBrowsable:(NSString*)key { } 

要么

 + (NSArray*)serializableProperties { } 

假设我们的class级名为FOOBar ,我们想知道baz键是否可浏览。 无需创buildFOOBar我们可以说:

 if ([FOOBar keyIsBrowsable:@"baz"]} { ... } 

你可以用这个技术来做很多事情,可以用自定义属性来完成。 (除了像编译器IIRC那样需要配合的Serializable属性之外)。然而,自定义属性的优点在于,一目了然地很容易区分元数据和该类的实际function的内在特性,但我认为这是一个小小的收获。

(当然,你可能需要检查keyIsBrowsable: selector的存在性,就像你必须检查是否存在一个特定的自定义属性一样,自定义属性在这里也有一些细节,因为我们可以告诉.NET运行时将它们全部交给我们。)

如果你想添加属性到属性,类,方法或伊娃,你可以尝试使用github.com/libObjCAttr 。 这很容易使用,通过cocoapods添加它,然后你可以添加像这样的属性:

 @interface Foo RF_ATTRIBUTE(YourAttributeClass, property1 = value1) @property id bar; @end 

在代码中:

 YourAttributeClass *attribute = [NSDate RF_attributeForProperty:@"bar" withAttributeType:[YourAttributeClass class]]; // Do whatever you want with attribute, nil if no attribute with specified class NSLog(@"%@", attribute.property1) 

序列化对象时遇到类似的问题。 我的解决scheme是添加@property (nonatomic, readonly) NSArray *serialProperties; 它有一个自定义getter,它返回应该被序列化的这个(子)类的属性的名字(如NSString *)。

例如:

 - (NSArray *)serialProperties { return @[@"id", @"lastModified", @"version", @"uid"]; } 

或者在一个子类中:

 - (NSArray *)serialProperties { NSMutableArray *sp = [super serialProperties].mutableCopy; [sp addObject:@"visibleName"]; return sp; } 

然后,您可以通过[self dictionaryWithValuesForKeys:self.serialProperties]轻松获取所有属性及其值。

除了sdk提供的内容,您不能添加自定义属性。 但是有一个工作要达到你的目标…

 @interface classTest:NSObject @property(strong,nonatomic)NSString *firstName; @property(strong,nonatomic)NSString *lastName; @property(strong,nonatomic)NSMutableDictionary *metaData; @end @implementation classTest - (id) init { self = [super init]; //Add meta data metaData=[[NSmutableDictionary alloc]init]; // if( !self ) return nil; return self; } @end 

所以使用字典添加和检索元数据…

我希望它可以帮助….