iOS 在组件中存储随机属性,例如没有子类的 UITextField

Posted

技术标签:

【中文标题】iOS 在组件中存储随机属性,例如没有子类的 UITextField【英文标题】:iOS Store random property in Component e.g. UITextField without Subclass 【发布时间】:2012-12-15 14:36:46 【问题描述】:

有谁知道是否有一种方法可以在不创建所述组件的子类的情况下在 Interface Builder 的用户定义的运行时属性部分中设置字符串之类的属性?例如,我想为界面中的每个组件存储一个元数据值,以便以后使用。我只是不想创建子类或每个组件来添加元数据属性。

这是我想出的一种方法。意见?

#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];

【问题讨论】:

关联对象技巧几乎就是这样做的方法;虽然你没有说你为什么要这样做。它似乎打破了 MVC,模糊了视图和控制器之间的界限。 我有超过 20 个视图的 2000 个输入字段。我正在尝试自动化一些将控件绑定到 ios 中相应实体和属性的过程 【参考方案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];

【讨论】:

以上是关于iOS 在组件中存储随机属性,例如没有子类的 UITextField的主要内容,如果未能解决你的问题,请参考以下文章

初使用ele ui input组件,无法输入

Android开发之自己定义UI组件和属性

如何在 Core Data(例如 NSRect)中存储非标准的持久属性?

UI组件:TextView及其子类

iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)

iOS开发UI篇—核心动画(基础动画)