熟悉新项目:应用Runtime(关联属性+方法交换)找到UIImage名字

2,689 阅读2分钟

(其实最快速的方法是通过Lookin来找到图片名字😄)在新接手的项目上做开发是比较慢的,尤其是开发、产品、设计都换了几波人的上了年纪的项目。其实我们还是可以通过一些途径来提高维护老项目的效率。比如今天(全新的开发人员、产品、设计)就碰到设计说新做的需求有一个切图是app中原来就有的,为了保持风格统一,沿用原来的切图。难道还需要定位到当前的页面对应的代码中去寻找相应图片的名字吗?如果后面的新需求有大量类似的图片怎么办?经过一番思考,确定了一种比较快速定位图片名字的方法。如下:

第一步:给UIImage添加name属性

利用runtimeUIImage的分类中给UIImage关联一个属性p_name,替换原来的imageNamed:方法,在自己的方法中将图片的名字保存到p_name中。

#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIImage (Name)
@end
NS_ASSUME_NONNULL_END
#import "UIImage+name.h"
#import <objc/runtime.h>

@implementation UIImage (Name)

- (void)setP_name:(NSString *)p_name {
    objc_setAssociatedObject(self, @selector(p_name), p_name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSString *)p_name {
    return objc_getAssociatedObject(self, _cmd);
}

+ (UIImage *)wsk_imageNamed:(NSString *)imageName {
    UIImage *image = [UIImage wsk_imageNamed:imageName];
    image.p_name = imageName;
    return image;
}

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{       
        [NSObject swizzleClassMethods:UIImage.class originalSelector: @selector(imageNamed:) swizzledSelector: @selector(wsk_imageNamed:)];
    });
}

+ (void)swizzleClassMethods:(Class)className originalSelector:(SEL)originalSel swizzledSelector:(SEL)swizzledSel {

    if (!className) return;

    Method origMethod = class_getClassMethod(className, originalSel);

    Method swizMethod = class_getClassMethod(className, swizzledSel);

    IMP origIMP = method_getImplementation(origMethod);

    IMP swizIMP = method_getImplementation(swizMethod);

    const char origType = method_getTypeEncoding(origMethod);

    const char swizType = method_getTypeEncoding(swizMethod);

    Class metaClass = object_getClass(className);

    BOOL didAddMethod = class_addMethod(metaClass, originalSel, swizIMP, swizType);

    if (didAddMethod) {
        class_replaceMethod(metaClass, swizzledSel, origIMP, origType);
    } 
    else {
        class_replaceMethod(metaClass,
                            swizzledSel,
                            class_replaceMethod(metaClass,
                                                originalSel,
                                                method_getImplementation(swizMethod),
                                                method_getTypeEncoding(swizMethod)),
                            method_getTypeEncoding(origMethod));
    }
}

@end

第二步:找到目标UIImageVIew的地址

  • 方法二:使用Chisel命令pviews

  • 方法三:使用工具FLEX找到UIImageVIew的地址。

第三步:打印图片的名字

使用LLDBpo命令 po [((UIImageView*)0x122203f40).image valueForKey:@"p_name"] 打印图片的名字。

注意: xib中设置的图片名字,打印为nil


视频转GIF步骤

  • 1、brew install ffmpeg
  • 2、ffmpeg -ss 00:00:00 -i flex.mov -s 375x667 -r "2" flex.gif