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

标签 objective-c ios interface-builder

有谁知道是否有一种方法可以在 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];

最佳答案

你可以在某个地方保留一个 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];

关于objective-c - iOS 在组件中存储随机属性,例如没有子类的 UITextField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13893112/

相关文章:

ios - 纵向和横向的 UICollectionView 单元格间距

xcode - Monotouch 5 之后 XIB 文件的使用

cocoa - 以编程方式设置 NSTextField 的文本

Xcode/Interface Builder,使用对象标签的定义/常量

iOS Google 跟踪代码管理器购买事件发送 0(零)作为数量参数

objective-c - 如何在 iOS 中不断将数据传递给另一个应用程序?

android - 如何在触摸时删除克隆

iphone - 自定义表格单元格背景图片

ios - NSFetchRequest 找不到实体名称的 NSEntityDescription

ios - iOS 17 中弃用了一堆 UIGraphics 方法,没有明确的替代方案?