V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
thuai
V2EX  ›  iOS

如何对 initXXXX 这系列方法进行 methods swizzling?

  •  
  •   thuai · 2015-04-07 16:09:04 +08:00 · 2514 次点击
    这是一个创建于 3311 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一般写initWithFrame:如下

    - (id)initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame]) {
            // do something ...
        }
        return self;
    }
    

    在网上看到经常有人进行这样的method swizzling,代码如下:

    - (id)swizzled_initWithFrame:(CGRect)frame
    {
        // This is the confusing part (article explains this line).
        id result = [self swizzled_initWithFrame:frame];
    
        // Safe guard: do we have an UIView (or something that has a layer)?
        if ([result respondsToSelector:@selector(layer)]) {
            // Get layer for this view.
            CALayer *layer = [result layer];
            // Set border on layer.
            layer.borderWidth = 2;
            layer.borderColor = [[UIColor redColor] CGColor];
        }
    
        // Return the modified view.
        return result;
    }
    
    
    + (void)load
    {
        Method original, swizzle;
    
        // Get the "- (id)initWithFrame:" method.
        original = class_getInstanceMethod(self, @selector(initWithFrame:));
    
        // Get the "- (id)swizzled_initWithFrame:" method.
        swizzle = class_getInstanceMethod(self, @selector(swizzled_initWithFrame:));
    
        // Swap their implementations.
        method_exchangeImplementations(original, swizzle);
    }
    

    想问下,swizzled_initWithFrame:这个方法中并没有发送[super initWithFrame]这个消息,那如何保证super initWithFrame了呢?

    v2ex上大神多,请轻喷!谢谢:)

    5 条回复    2015-04-08 16:14:07 +08:00
    ambitiouspei
        1
    ambitiouspei  
       2015-04-07 17:17:54 +08:00
    在load 方法里, swizzled_initWithFrame: 和 initWithFrame: 实现调换了,以后调用initWithFrame: 其实实际实现就是 swizzled_initWithFrame: -> initWithFrame: > (super) initWithFrame:
    wezzard
        2
    wezzard  
       2015-04-08 10:30:46 +08:00
    樓主連 Swizzle 的目標是哪個 class 都沒有搞清楚呢

    swizzled initializer 裏面訪問了 CALayer 的 designated initializer,足矣。
    thuai
        3
    thuai  
    OP
       2015-04-08 14:48:54 +08:00
    @wezzard 我只是没有写全代码而已。贴中的swizzle的目标类只要是有initWithFrame这个方法的类不是都可以么?
    wezzard
        4
    wezzard  
       2015-04-08 15:01:57 +08:00
    @thuai Sorry, 我看錯了。一樓說的是對的。
    thuai
        5
    thuai  
    OP
       2015-04-08 16:14:07 +08:00
    @wezzard 没关系。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   809 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 75ms · UTC 21:16 · PVG 05:16 · LAX 14:16 · JFK 17:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.