问题标签 [method-swizzling]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
4599 浏览

ios - 使用类别覆盖方法时如何调用原始实现?

我试图弄清楚事情是如何运作的。所以我想当我使用类别覆盖某些方法时,我会得到有趣的 NSLogs。

super 和 self 在这里不起作用。有没有办法调用 -hitTest:withEvent: 的原始实现?我想要的是每次在 UIView 上调用 -hitTest:withEvent: 时的 NSLog。

仅用于个人学习目的。我想看到事件传递的实际效果。

0 投票
5 回答
10306 浏览

ios - Method swizzling in Swift

There is a little problem with UINavigationBar which I'm trying to overcome. When you hide the status bar using prefersStatusBarHidden() method in a view controller (I don't want to disable the status bar for the entire app), the navigation bar loses 20pt of its height that belongs to the status bar. Basically the navigation bar shrinks.

enter image description here enter image description here

I was trying out different workarounds but I found that each one of them had drawbacks. Then I came across this category which using method swizzling, adds a property called fixedHeightWhenStatusBarHidden to the UINavigationBar class which solves this issue. I tested it in Objective-C and it works. Here are the header and the implementation of the original Objective-C code.

Now since I'm doing my app in Swift, I tried translating it to Swift.

The first problem I faced was Swift extension can't have stored properties. So I had to settle for computed property to declare the fixedHeightWhenStatusBarHidden property that enables me to set the value. But this sparks another problem. Apparently you can't assign values to computed properties. Like so.

I get the error Cannot assign to the result of this expression.

Anyway below is my code. It compiles without any errors but it doesn't work.

fixedHeightWhenStatusBarHidden() method in the middle is commented out because leaving it gives me a method redeclaration error.

I haven't done method swizzling in Swift or Objective-C before so I'm not sure of the next step to resolve this issue or even it's possible at all.

Can someone please shed some light on this?

Thank you.


UPDATE 1: Thanks to newacct, my first issue about properties was resolved. But the code doesn't work still. I found that the execution doesn't reach the load() method in the extension. From comments in this answer, I learned that either your class needs to be descendant of NSObject, which in my case, UINavigationBar isn't directly descended from NSObject but it does implement NSObjectProtocol. So I'm not sure why this still isn't working. The other option is adding @objc but Swift doesn't allow you to add it to extensions. Below is the updated code.

The issue is still open.


UPDATE 2: Jasper helped me to achieve the desired functionality but apparently it comes with a couple of major drawbacks.

Since the load() method in the extension wasn't firing, as Jasper suggested, I moved the following code block to app delegates' didFinishLaunchingWithOptions method.

And I had to hardcode the return value to 'true' in the getter of fixedHeightWhenStatusBarHidden property because now that the swizzling code executes in the app delegate, you can't set a value from a view controller. This makes the extension redundant when it comes to reusability.

So the question is still open more or less. If anyone has an idea to improve it, please do answer.

0 投票
4 回答
2881 浏览

objective-c - Objective-C Method Swizzling 示例不起作用

我想尝试 Method Swizzling 以清楚地了解它是如何工作的。查看此代码: http: //nshipster.com/method-swizzling/。我创建了一个类和一个类别,这是代码

类的实现

类别标题:

类别实施

这是主要的:

当我打电话时[cc newMethod],我得到了无限循环,根据我链接的文章,这不应该发生。我在这段代码中看不到错误。

0 投票
2 回答
490 浏览

objective-c - 存根 -[NSDate 初始化]

使用除 -[NSDate init] 之外的类别可以轻松地存根 NSDate 以返回模拟日期。-[NSDate init] 不像其他方法那样被调用。class_addMethod 没有帮助。method_exchangeImplementations, method_setImplementation on -[NSDate init] 实际上改变了 -[NSObject init] 但对 -[NSDate init] 没有影响。

输出是

NSDate+Mock.m

0 投票
0 回答
840 浏览

ios - 用于单元测试的新功能

简短说明:

NSDictionary 中的一个对象似乎被过度释放。涉及对象新功能的调配,并被认为是导致问题的原因。

长解释:

我正在为没有考虑单元测试的代码开发一些单元测试。为了用模拟对象替换代码中创建的对象,我使用了 swizzling。

我最近进行了以下设置:

  • 我有一个单例测试类,它基本上只包含一个测试数据字典。
  • 我有一个测试用例,它创建一个模拟对象(MockA),该对象应通过 swizzling 发送到测试函数,运行被测函数并检查结果。
  • 我有一个清理阶段

现在来一些代码:

测试用例(注意崩溃!!)

调酒功能

被测功能

有任何想法吗?

更新

为了找到错误,我尝试运行此代码:

崩溃线程 1: EXC_BAD_ACCESS(code=1, address=...) 在日志中: *** -[MockLoginOperation retain]: message sent to deallocated instance 0x7fd7b31f5050

0 投票
2 回答
633 浏览

ios - Objective-c IOS arm64方法调配失败调用原始方法

我在 ARMv7 IOS 设备上使用标准方法 swizzling,它对我来说非常完美。

但是当我为 arm64 编译代码时 - 它无法从新方法调用原始方法

我调配的主要目的 - 在另一种方法中使用来自我的应用程序内部方法的参数。

我有原始方法-(void)insertdata:(id)text,我想更改它-(void)patchedCall:(id)text并在新方法中调用原始方法。

代码:

代码在 arm64 架构上调用原始方法失败:

如何改进我的代码以在 armv7 和 arm64 上工作?

0 投票
1 回答
903 浏览

objective-c - Why does ARC cause EXC_BAD_ACCESS when swizzling functions using class_replaceMethod from objc runtime library?

I need to replace some methods’ implementations of specific Objective-C classes. A set of functions from objc/runtime library is capable of doing that. To simplify the issue I just write a simplest sample code as following:

#xA;

I just replace the original implementation of [MyClass func]. When compiler flag -fno-objc-arc is set, this code works just fine:

#xA;

But problem occurs when ARC is enabled(by setting compiler flag as -fobjc-arc). A EXC_BAD_ACCESS signal is thrown while invoking gOriginalFunc(as comments say). I don’t know the reason, could anyone tell?

0 投票
0 回答
168 浏览

ios - Objective-C 类标识符的前缀是 objc_class_ 而不是 _OBJC_CLASS_$_

我正在尝试在使用 Objective-C 制作的应用程序中调整一些方法。我收到此错误:

在 Hopper 中打开可执行文件后,我看到所有类都以前缀objc_class_代替。所以我试图调配的方法的类名是objc_class_IASAvatarViewController. 首先,我很想知道类标识符是如何变成这样的(某种名称修饰?)。其次,我想知道是否可以让我的 dylib 引用正确的标识符。

DylibTest.h:

DylibTest.m

以及带有 Objective-C 类的 Hopper 的屏幕截图: 霍珀的屏幕截图

编辑:获得足够的声誉可以直接发布图片。

Edit2: class-dump文件: http: //pastebin.com/DcUD5AL5

0 投票
1 回答
283 浏览

ios - UICollectionViewCell 方法混用

我在UITableViewCell类别上调配方法时出现意外行为

我的.m文件:

好吧,当我开始我的项目时,我有这个:

  1. 这是 100% 的一个UICollectionViewCell类别。
  2. 此时,在 中+(void) load,只有UITableViewCell类通过(如预期的那样)
0 投票
1 回答
330 浏览

objective-c - How to replace pickerView:numberOfRowsInComponent method for 1 instance of pickerView

I want to create a pickerView programmatically and have it use it's own version of a method like pickerView:numberOfRowsInComponent.

I create the instance at runtime like this:

The standard method called would be:

What I want to do is replace this standard method with another method for this instance only.

I've been able to use method swizzle to do this with other things, but I can't seem to get it to work with UIPickerView.

}

I've listed the methods to see if the 2nd method was added to the instance during runtime and it is in the list.

However, the 2nd method doesn't run, the 1st method does run.

Here's a link to the post that got me started on this, and I've confirmed it works, but I seem to be missing something about this. http://nshipster.com/method-swizzling/

I'm open to other suggestions, the problem I'm trying to solve is that I want to create the instance of a UIPickerView object that won't be dependent on another instance that will be running at the same time. So I want a different method that will work only with the one instance and completely ignore any other instances that might be running and I want to do this programmatically.

At lest one reason for not using a tag/switch, is that I don't know what the conditions will be until runtime.

I don't know why swizzle would work with one object and not another, and I'm open to other way to replace stock methods with others at runtime.

Is there something about the method I'm trying to replace that won't allow it to be replaced?

EDIT: in order to try and make the question clear, the following code in the link works. It swaps one method for another method. What I need to do is the same thing for another object and I can't figure out what it works for 1 object and not another.

This works for another object: http://nshipster.com/method-swizzling/

Here's another link as well: http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/