UINavigationBar
我正试图克服一个小问题.当您prefersStatusBarHidden()
在视图控制器中使用方法隐藏状态栏时(我不想禁用整个应用程序的状态栏),导航栏会丢失属于状态栏的高度的20pt.基本上导航栏缩小了.
我正在尝试不同的解决方法,但我发现它们中的每一个都有缺点.那时,我发现这次来到类别,其使用方法交叉混合,添加了一个名为属性fixedHeightWhenStatusBarHidden
的UINavigationBar
解决了这个问题类.我在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) 我必须测试一些日期计算但是这样做我需要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
总是当前的日期.
我基本上正在寻找一种方法来检测何时/什么第三方库调配.我最近遇到了一个广告库使用了AFNetworking的古怪分叉的情况.AFNetworking对NSURLSessionTask进行了调整,在某些情况下,这两个混合体并没有很好地发挥作用.我真的希望能够检测和理智检查这种事情,理想情况下甚至在应用程序中保留每个混合方法的版本化转储,这样我们就可以了解谁在修补什么以及风险是什么.谷歌和堆栈溢出搜索只发布了一堆关于如何调整的教程.有人遇到过这个问题或有解决方案吗?看起来我可能能够使用objc/runtime.h编写代码,但我无法想象我是第一个需要它的人.
我正在处理方法 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中使用方法调配时会出现什么性能损失?
哪个(如果有的话)编译器优化被消息调整打败了?
在NSHipter关于方法调配的文章中,它说"应该总是在dispatch_once中完成Swizzling".为什么这是必要的,因为每个类只发生一次加载?
方法是否会变得混乱并且是同样的混合?如果没有,那么什么是混合?
我试着弄清楚事情是如何运作的.所以我想当我用类别覆盖某些方法时,我会得到有趣的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
虽然可以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
?
Swift 4中的混合不再有效.
Method 'initialize()' defines Objective-C class method 'initialize', which is not permitted by Swift
这是我找到解决方案的事情所以想留下问题和答案给别人.
method-swizzling ×10
objective-c ×7
ios ×4
swift ×4
swizzling ×4
clang ×1
llvm ×1
mocking ×1
nsdate ×1
performance ×1
selector ×1
swift4 ×1
unit-testing ×1