标签: method-swizzling

方法在Swift中调整

UINavigationBar我正试图克服一个小问题.当您prefersStatusBarHidden()在视图控制器中使用方法隐藏状态栏时(我不想禁用整个应用程序的状态栏),导航栏会丢失属于状态栏的高度的20pt.基本上导航栏缩小了.

在此输入图像描述 在此输入图像描述

我正在尝试不同的解决方法,但我发现它们中的每一个都有缺点.那时,我发现这次来到类别,其使用方法交叉混合,添加了一个名为属性fixedHeightWhenStatusBarHiddenUINavigationBar解决了这个问题类.我在Objective-C中进行了测试,但它确实有效.以下是原始Objective-C代码的标题实现.

现在,因为我在Swift中使用我的应用程序,所以我尝试将其转换为Swift.

我遇到的第一个问题是Swift扩展无法存储属性.所以我不得不解决计算属性来声明fixedHeightWhenStatusBarHidden使我能够设置值的属性.但这引发了另一个问题.显然,您无法为计算属性赋值.像这样.

self.navigationController?.navigationBar.fixedHeightWhenStatusBarHidden = true
Run Code Online (Sandbox Code Playgroud)

我得到错误无法分配给这个表达式的结果.

无论如何,下面是我的代码.它编译没有任何错误,但它不起作用.

import Foundation
import UIKit

extension UINavigationBar {

    var fixedHeightWhenStatusBarHidden: Bool {
        return objc_getAssociatedObject(self, "FixedNavigationBarSize").boolValue
    }

    func sizeThatFits_FixedHeightWhenStatusBarHidden(size: CGSize) -> CGSize {

        if UIApplication.sharedApplication().statusBarHidden && fixedHeightWhenStatusBarHidden {
            let newSize = CGSizeMake(self.frame.size.width, 64)
            return newSize
        } else {
            return sizeThatFits_FixedHeightWhenStatusBarHidden(size)
        }

    }
    /*
    func fixedHeightWhenStatusBarHidden() -> Bool {
        return objc_getAssociatedObject(self, "FixedNavigationBarSize").boolValue
    }
    */

    func setFixedHeightWhenStatusBarHidden(fixedHeightWhenStatusBarHidden: Bool) …
Run Code Online (Sandbox Code Playgroud)

objective-c ios swift method-swizzling

10
推荐指数
1
解决办法
9135
查看次数

如何在Swift中模拟NSDate?

我必须测试一些日期计算但是这样做我需要NSDate()在Swift中进行模拟.整个应用程序是用Swift编写的,我也想在其中编写测试.

我试过方法调整但它不起作用(或者我做错了什么更有可能).

extension NSDate {
    func dateStub() -> NSDate {
        println("swizzzzzle")
        return NSDate(timeIntervalSince1970: 1429886412) // 24/04/2015 14:40:12
    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

func testCase() {
    let original = class_getInstanceMethod(NSDate.self.dynamicType, "init")
    let swizzled = class_getInstanceMethod(NSDate.self.dynamicType, "dateStub")
    method_exchangeImplementations(original, swizzled)
    let date = NSDate()
// ...
}
Run Code Online (Sandbox Code Playgroud)

date总是当前的日期.

unit-testing mocking nsdate swift method-swizzling

9
推荐指数
3
解决办法
4367
查看次数

有没有办法列出iOS应用程序中的所有混合方法?

我基本上正在寻找一种方法来检测何时/什么第三方库调配.我最近遇到了一个广告库使用了AFNetworking的古怪分叉的情况.AFNetworking对NSURLSessionTask进行了调整,在某些情况下,这两个混合体并没有很好地发挥作用.我真的希望能够检测和理智检查这种事情,理想情况下甚至在应用程序中保留每个混合方法的版本化转储,这样我们就可以了解谁在修补什么以及风险是什么.谷歌和堆栈溢出搜索只发布了一堆关于如何调整的教程.有人遇到过这个问题或有解决方案吗?看起来我可能能够使用objc/runtime.h编写代码,但我无法想象我是第一个需要它的人.

objective-c objective-c-runtime ios method-swizzling

9
推荐指数
1
解决办法
1256
查看次数

从 swizzled 函数调用原始函数

我正在处理方法 swizzling,并想在执行method_exchangeImplementations. 我为此设置了两个项目。

第一个项目是应用程序的主项目。该项目包括应用程序的所有逻辑。请注意,originalMethodName在视图加载时调用。

@implementation ViewController

- (void)originalMethodName 
{
    NSLog(@"REAL %s", __func__);
}

- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"REAL %s", __func__);

    [self originalMethodName];
}

@end
Run Code Online (Sandbox Code Playgroud)

第二个项目仅包含用于 swizzling 的代码。我有一个方法swizzle_originalMethodName,其中包含我想注入到主应用程序的originalMethodName代码,并调用函数。

@implementation swizzle_ViewController

- (void)swizzle_originalMethodName
{
    NSLog(@"FAKE %s", __func__);
}

__attribute__((constructor)) static void initializer(void)
{
    NSLog(@"FAKE %s", __func__);

    Class c1 = objc_getClass("ViewController");
    Class c2 = [swizzle_ViewController class];
    Method m1 = class_getInstanceMethod(c1, @selector(originalMethodName));
    Method m2 = class_getInstanceMethod(c2, @selector(swizzle_originalMethodName));
    method_exchangeImplementations(m1, m2);
}

@end
Run Code Online (Sandbox Code Playgroud)

swizzle 工作得很好(如下面的输出所示),但现在我希望能够originalMethodName从 …

objective-c swizzling method-swizzling

9
推荐指数
2
解决办法
3751
查看次数

Objective-C方法调配性能

在Objective-C中使用方法调配时会出现什么性能损失?

哪个(如果有的话)编译器优化被消息调整打败了?

performance objective-c llvm clang method-swizzling

8
推荐指数
1
解决办法
273
查看次数

在方法调配中使用dispatch_once

在NSHipter关于方法调配的文章中,它说"应该总是在dispatch_once中完成Swizzling".为什么这是必要的,因为每个类只发生一次加载?

objective-c objective-c-runtime method-swizzling

7
推荐指数
1
解决办法
900
查看次数

方法是否会变得混乱并且是同样的混合?

方法是否会变得混乱并且是同样的混合?如果没有,那么什么是混合?

objective-c swizzling isa-swizzling method-swizzling

7
推荐指数
1
解决办法
2298
查看次数

如何在覆盖带有类别的方法时调用原始实现?

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

@implementation UIView(Learning)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"-hitTest:withEvent: event=%@", event);
    return [self hitTest:point withEvent:event];
}
@end
Run Code Online (Sandbox Code Playgroud)

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

这仅用于个人学习目的.我希望看到活动的实施.

objective-c swizzling ios objective-c-category method-swizzling

6
推荐指数
1
解决办法
4263
查看次数

快速处理属性的方法

虽然可以setMyProperty:在obj-c中替换方法,但我想知道如何快速进行?

例如我要替换UIScrollView::setContentOffset:

let originalSelector: Selector = #selector(UIScrollView.setContentOffset)
let replaceSelector: Selector = #selector(UIScrollView.setContentOffsetHacked)
...
Run Code Online (Sandbox Code Playgroud)

...但是执行后originalSelector包含setContentOffset:animaed。那么,如何将属性的设置方法传递给selector

objective-c-runtime selector ios swift method-swizzling

6
推荐指数
2
解决办法
2498
查看次数

方法在swift 4中调整

Swift 4中的混合不再有效.

Method 'initialize()' defines Objective-C class method 'initialize', which is not permitted by Swift

这是我找到解决方案的事情所以想留下问题和答案给别人.

swizzling swift method-swizzling swift4

6
推荐指数
1
解决办法
5822
查看次数