请教一个 Swizzle method 的问题.

2016-02-25 12:39:00 +08:00
 xieweizhi007

我想通过JRSwizzle来对UIViewController的一些生命周期的方法进行时间统计.

代码如下:

[self jr_swizzleMethod:@selector(viewDidLoad) withMethod:@selector(ri_viewDidLoad) error:nil];
- (void)ri_viewDidLoad {
    NSDate *start = [NSDate date];

    [self ri_viewDidLoad];

    NSDate *end = [NSDate date];
    NSTimeInterval elapsed = [end timeIntervalSinceDate:start];

    NSLog(@"Elapsed:%f(s)",elapsed);
}

可是我在 view controller 的- viewDidLoad方法中执行 sleep(), 是采集不到这个时间的, 请问这里有什么问题吗?

3753 次点击
所在节点    iDev
22 条回复
randm
2016-02-25 12:49:58 +08:00
你要用 ri_viewDidLoad
xieweizhi007
2016-02-25 14:39:27 +08:00
@randm 这里是没问题的, 用 ri_viewDidLoad 就会死循环啦. 因为 ri_viewDidLoad 里面调用的 ri_viewDidLoad 其实是原来的 viewDidLoad 方法.
zhicheng
2016-02-25 16:02:32 +08:00
1. 你想统计时间,这和 MethodSwizzling 有什么关系?
2. 你 Swizzling viewDidLoad 有什么用?
xieweizhi007
2016-02-25 16:20:11 +08:00
@zhicheng , 我是想通过这种方法来统计所有 Controller 的生命周期的运行效率.
chmlai
2016-02-25 16:33:02 +08:00
代码看起来没有错, 分别在 ri_viewDidLoad 和 viewDidiLoad 里面 Log 一下看看
xieweizhi007
2016-02-25 16:54:55 +08:00
@chmlai 原始的 viewDidLoad 也不需要 log 的, sleep 之后确实会卡顿. 而 ri_viewDidLoad 方法却是不正确的.
LINAICAI
2016-02-25 17:21:48 +08:00
[self ri_viewDidLoad];
这不对吧,不是应该[super ri_viewDidLoad];??
juxingzhutou
2016-02-25 18:57:42 +08:00
你的 jr_swizzleMethod 是在哪里调用的?我觉得问题可能在 swizzling 的次数上。

贴上更完整的代码有利于大家判断。
juxingzhutou
2016-02-25 18:58:30 +08:00
@LINAICAI method swizzling 就是调用自身 selector 来调用原版方法的。
tedzhou
2016-02-25 19:06:37 +08:00
是不是有其他信号相关的代码把线程唤醒了?
xieweizhi007
2016-02-25 19:18:48 +08:00
@juxingzhutou 是的是的.
xieweizhi007
2016-02-25 19:19:03 +08:00
@tedzhou 没有, 你可以看看.
tedzhou
2016-02-25 20:02:30 +08:00
swizzle 不能把 subClass 的方法也交换的哦
juxingzhutou
2016-02-25 20:07:57 +08:00
13 楼说得对,我再补充解释一下。你的代码的问题是这样的,实际上你 swizzling 的方法是子类中的`[super viewDidLoad]`这个方法。

也就是说 sleep 是在你的 ri_viewDidLoad 方法执行完之后才执行的,`[super viewDidLoad]`执行的才是 ri_viewDidLoad 方法。
xieweizhi007
2016-02-26 09:18:45 +08:00
@tedzhou
@juxingzhutou

我大概懂了, 谢谢 ^ ^
wezzard
2016-02-26 14:14:30 +08:00
我建議你啓動時掃描所有 classes 然後找到目標做 is-a swizzle ,做一個 wrapper wrap 住所有要統計的 class ,控制住所有消息發送。但是就是肯定會影響性能。
xieweizhi007
2016-02-26 14:47:06 +08:00
@wezzard 我目前就是这样做的, 是有性能影响 😀
Python666666
2017-02-08 10:32:20 +08:00
@xieweizhi007 可以分享一下你的解决方案吗
xieweizhi007
2017-02-08 19:23:15 +08:00
@Python666666 跟 @wezzard 说的方案一样
Python666666
2017-02-14 15:16:56 +08:00
@wezzard 不是很懂,可以分享一下 Demo 吗, sshare@qq.com,感恩

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/259024

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX