I'm trying to add some information to a UIImage
I am doing some experimentation with to add details like the number of UILabel
's present on the screen and their frames.
I tried using setValue:forKeyPath:
but this does not work since UIImage
is not key-value compliant. What is an efficient way to do this?
Adding metadata using the CGImageMetadata
API's seems to need me to convert the UIImage
to NSData
. Also, I would like to access the data without saving it every time. Can anyone point me to a good way to do this?
CodePudding user response:
You can get use of associated objects to complement objects of classes source of which you don't have access to with some additional data (with use of objc_setAssociatedObject
to set and objc_getAssociatedObject
to read the data):
UIImage *image = [UIImage new];
NSString *extraData = @"extra info";
objc_setAssociatedObject(image, @"example", extraData, OBJC_ASSOCIATION_COPY_NONATOMIC);
NSLog(@"%@", objc_getAssociatedObject(image, @"example"));
For convenience it can be effectively wrapped with a property by extending the class with a category:
// UIImage TDWExtraData.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIImage (TDWExtraData)
@property (nonatomic, copy) NSString *tdw_extraData;
@end
NS_ASSUME_NONNULL_END
// UIImage TDWExtraData.m
#import "UIImage TDWExtraData.h"
#import <objc/runtime.h>
static void const *const kExtraDataKey = &kExtraDataKey;
@implementation UIImage (TDWExtraData)
- (NSString *)tdw_extraData {
return objc_getAssociatedObject(self, kExtraDataKey);
}
- (void)setTdw_extraData:(NSString *)data {
objc_setAssociatedObject(self, kExtraDataKey, data, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end
P.S. It's not correct to say that UIImage
is not KVC compliant only because it doesn't support setValue:forKeyPath:
for non-existing key paths. It's perfectly compliant for key-paths the class has defined:
UIImage *obj = [UIImage new];
NSLog(@"%@", [obj valueForKey:@"size"]); // prints size