一般通过扩展添加私有属性,仅供内部调用,不对外开放。分类一般添加方法,供外部调用,项目中常见,UI类常常用分类来封装系统方法,但分类添加属性就很少用到了。通过Runtime动态绑定属性,来添加属性,实现某些操作。
下面,来给NSObject添加name属性,系统已经提供了关联、移除的一些方法。要实现getter、setter方法,因为系统内部没有实现,初始的时候内存已经分配布置好了。在调用的时候,打印对象,会发现属性并没有在里面,只能通过实现的getter、setter方法来访问属性。
// Copyright © 2020 Apple. All rights reserved.
#import
NS_ASSUME_NONNULL_BEGIN
@interfaceNSObject(Property)
@property(strong, nonatomic) NSString *name;
@end
NS_ASSUME_NONNULL_END
//
// NSObject+Property.m
// Copyright © 2020 Apple. All rights reserved.
#import "NSObject+Property.h"
#import "objc/message.h"
static const char *key = "name";
@implementation NSObject (Property)
// setter 绑定当前对象
- (void)setName:(NSString*)name {
// self:当前绑定的对象、
objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// getter
- (NSString*)name {
// 由关联的key,获取关联的属性。
return objc_getAssociatedObject(self, key);
}
@end
这样就给NSObject添加了实例属性,可以在必要的时候设置属性值,需要时候获取属性值。下面再具体操作一下,拿UIImage来操作,实现分类方法。
// UIImage+add.h
// Copyright © 2020 Apple. All rights reserved.
NS_ASSUME_NONNULL_BEGIN
@interface UIImage (add)
@property(strong, nonatomic) NSString *imageName;
+ (UIImage*)imageWithName:(NSString*)name;
@end
NS_ASSUME_NONNULL_END
// UIImage+add.m
// Copyright © 2020 Apple. All rights reserved.
#import "UIImage+add.h"
#import
static NSString *imageNameKey = @"imageNameKey";
@implementation UIImage (add);
// setter
- (void)setImageName:(NSString*)imageName {
objc_setAssociatedObject(self, &imageNameKey,imageName, OBJC_ASSOCIATION_COPY);
}
// getter
- (NSString *)imageName {
return objc_getAssociatedObject(self, &imageNameKey);
}
+ (UIColor*)imageWithName:(NSString*)name {
UIImage *image = [xxx imageNamed: xxx(name)(index)];// 一些操作
image.imageName= name;// 绑定属性
return image ;
}
@end
好了,接下来在视图里面,new一个UIImageView *imgV,设置图片:
imgV.image = [UIImage imageWithName:xxx ];
在上面实现的分类方法里,设置了imgV.image.imageName为 imageWithName:传入的值,这时,imgV.image对象已经绑定了属性imageName,关联起来了。
一般界面上都有不少UIImageView等UI控件,在适当时机存储起来,在需要修改的时候,拿出来,看看它们的imageName属性有没有。有的话,说明可以修改了,根据imageName属性来进行特定操作。
分割线、未完,待补充