有没有人知道是否有办法在Interface Builder的User Defined Runtime Atributes部分中设置类似字符串的属性而不创建所述组件的子类?例如,我想为我后面使用的界面中的每个组件存储元数据值。我只是不想创建子类或每个组件来添加元数据属性。
这是我提出的一种方法。意见?
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@interface UIControl(MetaData)
@property (nonatomic, retain) id entityProperty;
@end
@implementation UIControl(MetaData)
static char const * const EntityPropertyKey = "EntityProperty";
@dynamic entityProperty;
- (id)entityProperty {
return objc_getAssociatedObject(self, EntityPropertyKey);
}
- (void)setEntityProperty:(id)newEntityProperty {
objc_setAssociatedObject(self, EntityPropertyKey, newEntityProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
...
if (textField.entityProperty)
[managedObject setValue: textField.text forKey:textField.entityProperty];
答案 0 :(得分:1)
你可以将NSDictionary保存在某个地方,也许是在单个对象中,该对象具有为对象发出唯一ID并通过字典中的id键存储元数据的方法。如果你的id只是递增的整数,那么UI对象有一个你可以使用的标记属性。然后字典键只是那些唯一整数的NSNumbers。
像这样:
#import <Foundation/Foundation.h>
@interface ACLMetadataManager : NSArray
+(ACLMetadataManager*) sharedMetadataManager;
-(NSUInteger) getUniqueId;
-(void) setObject: (id) object forId:(NSUInteger) theId;
-(id) objectForId:(NSUInteger) theId;
@end
和
#import "ACLMetadataManager.h"
@implementation ACLMetadataManager { // Private variables
NSMutableDictionary *_metadata;
NSUInteger _ids;
}
- (id)init {
self = [super init];
if (self) {
_metadata = [[NSMutableDictionary alloc] init];
}
return self;
}
+(ACLMetadataManager*) sharedMetadataManager { // Singleton getter
static ACLMetadataManager *instance;
if (instance != nil) {
return instance;
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
static dispatch_once_t oneTimeThread;
dispatch_once(&oneTimeThread, ^(void) {
instance = [[ACLMetadataManager alloc] init];
});
#else
@synchronized(self) {
instance = [[ACLMetadataManager alloc] init];
}
#endif
return instance;
}
-(NSUInteger) getUniqueId { // Increment unique id when getter is called.
return ++_ids; // Start from 1 because tag is 0 by default.
}
-(void) setObject: (id) object forId:(NSUInteger) theId {
[_metadata setObject:object forKey:[NSNumber numberWithInteger:theId]];
}
-(id) objectForId:(NSUInteger) theId {
return [_metadata objectForKey:[NSNumber numberWithInteger:theId]];
}
// Override some methods to ensure singleton stays instantiated.
- (id) retain {
return self;
}
- (oneway void) release {
// Does nothing here.
}
- (id) autorelease {
return self;
}
- (NSUInteger) retainCount {
return INT32_MAX;
}
@end
用法:
ACLMetadataManager *metadataManager = [ACLMetadataManager sharedMetadataManager];
myControl.tag = [metadataManager getUniqueId];
[metadataManager setObject:myMetadata forId:myControl.tag];