万维网网站,个人申请网站,经常使用什么对网页的布局进行控制,全球网站排名查询类和实例的操作
iOS 运行时#xff08;Objective-C Runtime#xff09;提供了丰富的 API 来对类进行动态操作#xff0c;包括创建类、修改类的结构、添加方法、替换方法等。这对于实现动态特性、AOP#xff08;面向切面编程#xff09;、方法拦截等功能非常重要。以下举例…类和实例的操作
iOS 运行时Objective-C Runtime提供了丰富的 API 来对类进行动态操作包括创建类、修改类的结构、添加方法、替换方法等。这对于实现动态特性、AOP面向切面编程、方法拦截等功能非常重要。以下举例
创建并注册类(objc_allocateClassPair、objc_registerClassPair)关联对象objc_setAssociatedObject、objc_getAssociatedObject添加、替换方法class_addMethod、class_replaceMethod获取类的信息class_copyPropertyList、class_copyMethodList
1. 创建类和元类
API: objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)创建一个新的类并指定其父类及额外的内存空间。 objc_registerClassPair(Class cls)注册类以使其能够使用。
#import objc/runtime.hvoid dynamicMethodIMP(id self, SEL _cmd) {NSLog(Dynamic method invoked!);
}- (void)createDynamicClass {// 创建一个新类继承自NSObjectClass newClass objc_allocateClassPair([NSObject class], DynamicClass, 0);// 为类添加一个方法class_addMethod(newClass, selector(dynamicMethod), (IMP)dynamicMethodIMP, v:);// 注册类objc_registerClassPair(newClass);// 创建实例并调用动态方法id instance [[newClass alloc] init];[instance performSelector:selector(dynamicMethod)];
}动态创建类和元类在实际业务中的应用场景主要集中在以下方面
框架封装与底层实现如 KVO、AOP、热修复。插件化与组件化按需加载模块提升扩展性。跨平台 UI 框架支持动态生成控件映射类。 2. 添加属性或者关联对象
通过class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) 添加属性。
- (void)addDynamicProperty {objc_property_attribute_t type { T, \NSString\ }; // 属性类型objc_property_attribute_t ownership { C, }; // C代表copyobjc_property_attribute_t backingivar { V, _dynamicProperty }; // 关联ivarobjc_property_attribute_t attrs[] { type, ownership, backingivar };class_addProperty([self class], dynamicProperty, attrs, 3);
}需要注意的是这样添加完成之后并不能访问属性因为它不会自动生成访问方法getter、setter如果要用还需要通过前面的添加方法来配置getter、setter。真想不通这玩意有啥用反正我没用过。
倒不如咱们经常用的借助类别属性关联来的直接不过这不是动态特性了。
/// .h文件
interface UIImage (Help)/// name
property (nonatomic, copy) NSString *imageName;end/// .m文件
implementation UIViewController(Help)- (NSString *)imageName {return objc_getAssociatedObject(self, selector(imageName));
}- (void)setImageName:(NSString *)imageName {objc_setAssociatedObject(self, selector(imageName), imageName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}end 3. 添加、替换方法
API: class_addMethod(Class cls, SEL name, IMP imp, const char *types)添加方法。 class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)替换方法如果方法不存在则添加。 method_setImplementation(Method m, IMP imp)修改方法实现。
void newMethodIMP(id self, SEL _cmd) {NSLog(New method implementation called!);
}- (void)addOrReplaceMethod {Class cls [TestClass class];SEL originalSelector selector(oldMethod);SEL newSelector selector(newMethod);// 替换方法Method originalMethod class_getInstanceMethod(cls, originalSelector);class_replaceMethod(cls, originalSelector, (IMP)newMethodIMP, method_getTypeEncoding(originalMethod));
}
以上替换后我们再执行TestClass的oldMethod就会打印New method implementation called!
4. 获取类和方法信息
API:
class_getName(Class cls) 获取类名class_getSuperclass(Class cls) 获取父类class_getInstanceMethod(Class cls, SEL name) 获取实例方法class_getClassMethod(Class cls, SEL name) 获取类方法class_copyMethodList(Class cls, unsigned int *outCount) 获取方法列表
- (void)listMethodsOfClass:(Class)cls {unsigned int methodCount 0;Method *methodList class_copyMethodList(cls, methodCount);for (unsigned int i 0; i methodCount; i) {SEL methodName method_getName(methodList[i]);NSLog(Method: %, NSStringFromSelector(methodName));}free(methodList);
}以上自己实操看看效果更好一些