我想创建一个UIImage类的类,它将自己处理
(UIImage*) imageNamed:(NSString*) name
将为我保存名称作为创建图像属性的方法。为了做到这一点,我为这个方法创建了一个混合体,并为我的新添加的setter和getter属性创建了相关的引用。最后,实现看起来像这样:
@interface UIImage (MTReady)
@property(assign) NSString* imageName;
-(NSString*) getImageName;
@end
NSString * const imageNameKey = @"imageNameKey";
@implementation UIImage (MTReady)
@dynamic imageName;
-(NSString *)getImageName {
NSString* name = objc_getAssociatedObject(self, &imageNameKey);
return name;
}
-(void) setImageName:(NSString *)name {
objc_setAssociatedObject(self, &imageNameKey, name, OBJC_ASSOCIATION_ASSIGN);
}
+(void)load {
if(self == [UIImage class]) {
Method originalImageNamed, swizzledImageNamed;
originalImageNamed = class_getClassMethod(self, @selector(imageNamed:));
swizzledImageNamed = class_getClassMethod(self, @selector(swizzledImageNamed:));
method_exchangeImplementations(originalImageNamed, swizzledImageNamed);
}
}
+(UIImage *)swizzledImageNamed:(NSString*) name {
UIImage* image = [self swizzledImageNamed:name];
if(image)
[image setImageName:name];
return image;
}
@end
这个解决方案似乎不起作用,因为每当我在使用方法 imageNamed 创建的UIImage上调用 getImageName 时,我总是得到 nil 。我目前没有想法为什么会这样。我的实施中是否缺少某些内容?
答案 0 :(得分:0)
问题在于
objc_setAssociatedObject(self, &imageNameKey, name, OBJC_ASSOCIATION_ASSIGN);
应该是
objc_setAssociatedObject(self, &imageNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
或
objc_setAssociatedObject(self, &imageNameKey, name, OBJC_ASSOCIATION_COPY);
不要使用OBJC_ASSOCIATION_RETAIN
或OBJC_ASSOCIATION_RETAIN_NONATOMIC
,因为字符串可能是可变的。将字符串属性声明为copy而不是strong的完全相同的原因。
当我测试下面的代码时,正确设置和检索关联。
@implementation UIImage (Name)
static char const imageNameKey;
-(NSString *)getImageName {
NSString* name = objc_getAssociatedObject(self, &imageNameKey);
return name;
}
-(void) setImageName:(NSString *)name {
objc_setAssociatedObject(self, &imageNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
+(void)load {
if(self == [UIImage class]) {
Method originalImageNamed, swizzledImageNamed;
originalImageNamed = class_getClassMethod(self, @selector(imageNamed:));
swizzledImageNamed = class_getClassMethod(self, @selector(swizzledImageNamed:));
method_exchangeImplementations(originalImageNamed, swizzledImageNamed);
}
}
+(UIImage *)swizzledImageNamed:(NSString*) name {
UIImage* image = [self swizzledImageNamed:name];
if(image)
[image setImageName:name];
return image;
}
@end