问题标签 [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 投票
5 回答
225 浏览

c++ - 使用整数的 C++ 模板化数组运算符 []

我正在尝试操作一个特殊的结构,我需要某种 swizzle 运算符。为此,有一个重载的数组运算符是有意义的[],但我不想有任何分支,因为结构的特定规范允许理论上的解决方法。

目前,该结构如下所示:

我可以/应该做些什么来避免分支?我的想法是使用带有整数参数的模板并定义特化,但尚不清楚它是否有意义以及该怪物的语法可能是什么样的。

我明确地,在任何情况下都不能使用float[4]数组来合并两者(同样,没有联合技巧)。如果你需要一个很好的理由,那是因为float[2]它们实际上类似于特定于平台的 PowerPC 配对单曲。普通的 Windows 编译器不适用于成对的单曲,这就是我用float[2]s 替换代码的原因。

使用 GreenHills 编译器,我得到了这个程序集输出(这表明确实发生了分支):

该片段对应的 C++ 代码应该是这个:

0 投票
3 回答
1694 浏览

ios - 更改大型应用程序中每个 UILabel 的字体

这是一个有趣的问题:

我们正在重新设计整个应用程序,其中包含超过 100,000 行代码和近 100 个 XIB 文件。新设计要求(几乎)应用程序中的每个标签都使用新的自定义字体,而旧应用程序使用 Helvetica Neue 的默认字体。

尽可能多地更改 UILabel 的最有效方法是什么?我们不想手动更改代码和 XIB 中的数千个标签(这尤其困难,因为我们使用的是非系统字体)。

我们已经讨论了将 UILabel 的创建方法调整为默认使用新的自定义字体,这仍然允许在创建后自定义 Helvetica Neue 中保留的少数标签。

想法?

0 投票
1 回答
226 浏览

objective-c - 如何在方法 IMP 之间传递 va_list?(目标 c)

我正在尝试调配一个函数并使用函数 args 调用原始实现。新 IMP 的形式为:

这显然是错误的,因为args现在包含 _cmd 而...没有。

我怎样才能传递...给 originalImp?

0 投票
1 回答
1199 浏览

ios - iOS 静态库不起作用

我按照本文中的说明创建了一个静态库:

http://developer.apple.com/library/ios/#technotes/iOSStaticLibraries/Articles/creating.html

我为 iPhone 模拟器目标构建了它。它构建成功,然后我导入到一个我想使用它的新项目中。它导入正常并且没有问题,但是该库不起作用。我没有调用任何库方法;相反,该库的目的是调整 UIViewController viewDidAppear 方法,以便每次 UIViewController 出现时都会执行一段代码。尽管我的库包含在“使用库链接二进制文件”构建阶段,但这段代码没有被调用。

我知道问题不在于代码本身,因为如果我将原始 .m 和 .h 源文件不作为库导入,则一切正常。

0 投票
1 回答
297 浏览

objective-c - objc_setAssociatedObject 为所有子类设置一个类别

我有一个自定义容器视图控制器来管理我的应用程序的视图层次结构。我知道每个控制器都是这个容器控制器的某种孩子。我认为在 UIViewController 上有一个类别会很好,它允许我访问容器控制器,无论我在层次结构中的哪个位置。

这涉及到控制器层次结构的递归遍历,所以我认为最好尝试每个控制器只执行一次遍历。因此,使用 objc_setAssociatedObject,我在找到它后设置容器并设置一个标志,以便我知道是否需要在后续调用中遍历层次结构(我计划在 viewcontroller 曾经移动时使其无效,但这可能是矫枉过正,而我并没有那么远)。

无论如何,这在大多数情况下都可以正常工作,除了我的层次结构是否已遍历的标志似乎附加到 UIViewController,而不是 UIViewController 的特定子类。

我调配了 +load 以尝试在我的关联对象上设置默认值,但无济于事。

有任何想法吗?如何获取类别中的关联对象以与定义该类别的类的子类相关联?

这是我的代码,很好。

现在我已经辞职,在必要时手动设置属性。

0 投票
6 回答
11348 浏览

ios - 关于如何从所需设备捕获“尝试插入零对象”的建议

这是一种情况:Hockeyapp 和 testflight 时不时抱怨我

“试图插入零对象”

在可变字典/数组中。我知道正确的做法是始终检查 nil,并且在有意义时我会这样做。我们的测试人员无法捕捉到这些崩溃,但 AppStore 用户显然可以。

我的猜测是,有时服务器不应该返回 NSNulls。所以不要在这个庞大的项目中到处插入对 nil 的检查,我的想法是为测试人员创建一个单独的目标,并为集合类使用方法调配。说,我将替换insertObject:atIndex为 my swizzled_insertObject:atIndex,如果对象实际上是 nil,我会在它崩溃之前记录/显示描述性报告。

问题是我不能使用 swizzling for __NSPlaceholderDictionaryor __NSArrayM (只是因为我不能在私人课程上创建一个类别),这让我很伤心。

所以基本上我是在寻求关于如何捕捉那些令人讨厌的罕见崩溃的建议。我想到的一种解决方案是使用 try-catch 块,我知道它们在 Objective-c 中很昂贵,所以我不会在生产中使用它们,只是为了测试人员。但是被try-catche-s 包围的#ifdef方法被 -s 包围#endif会抹去代码的所有可读性。所以我正在寻找一个更优雅的解决方案。谢谢。

更新:不幸的是,堆栈跟踪不是很有描述性,这就是我得到的

0 投票
1 回答
1273 浏览

ios - iOS - EXC_BAD_ACCESS 代码 = 1 UIWebView 在(方法调配)初始化后崩溃

我刚刚将我的应用程序切换到了 ARC。由于 Xcode 提供的重构工具,转换取得了部分成功。一个不起作用的部分是一个奇怪的错误。

我使用了方法 swizzling (method_exchangeImplementations),所以它不会调用 UIView 的 initWithFrame,而是调用我的 myInitWithFrame 代码。重构过程在myInitWithFrame的方法声明处抛出了错误,所以我在方法声明之后添加了__属性__ ((objc_method_family(init)))。现在这一切都适用于 iOS 6.0 及更高版本,但在 iOS 5.0(我想支持的最低 iOS)上它不起作用。我得到一个 EXC_BAD_ACCESS(代码=1,地址=0X28)。每次运行都会出现完全相同的内存地址。

我有一个 UIWebView 调用它:

在 myInitWithFrame 进行初始化后,它返回 self,然后崩溃。在线程跟踪中,它说它在 [UIWebView 保留] 方法上的苹果代码中崩溃(该方法显示为灰色),如下所示。

抱歉,线程跟踪的格式不是很好,我没有足够的代表来发布图像。

有什么理由为什么相同的代码适用于 iOS 6.0,但不适用于 iOS 5.0?

0 投票
1 回答
507 浏览

ios - 方法调配实施未发生

我正在尝试学习调酒的概念。

即使我已经添加了method_exchangeImplementations,方法仍然没有被混合。关于我要去哪里错的任何想法?

0 投票
2 回答
2532 浏览

ios - 使用可变参数调整方法并转发消息 - 访问错误

我正在实现一个“代码注入器类”,通过方法调配可以让你有可能做这样的事情:

aSelector可以是具有可变数量的参数和可变返回类型的方法。参数 / 和返回类型可以是对象或原始类型。

首先,我附上代码,injectCodeBeforeSelector:让您了解我在做什么(我删除了代码中不感兴趣的部分):

基本上,我使用 class_addMethod 将 fake/swizzle 方法添加到目标类,然后进行 swizzle。该方法的实现设置为这样的函数:

现在的问题是:我在最后一行有一个 EXC_BAD_INSTRUCTION (objc_msgSend_corrupt_cache_error ())。如果我将 va_list 参数转发给假选择器,就会出现问题。如果我将最后一行更改为

没有错误,但显然无限递归开始了。

我试图:

  • 使用 va_copy
  • 在发送消息之前删除 swizzle

但没有结果。我认为问题与这个事实有关:va_list 不是一个简单的指针,它可以是类似于相对于方法的堆栈地址的偏移量的东西。所以,我不能用另一个函数(非混合函数)的 arg 列表调用函数(混合函数)的 objc_msgsend。

我试图改变方法并复制 NSInvocation 中的所有参数,但我在管理调用的返回值时遇到了其他问题,甚至一个一个地复制参数(管理所有不同的类型)需要大量代码,所以我更喜欢返回对于这种方法,这对我来说似乎更清洁(恕我直言)

你有什么建议吗?谢谢

0 投票
1 回答
408 浏览

ios - UIResponder 的 Swizzling Copy 方法

我正在调整 UIResponder 的 Copy: 和 Paste: 方法。我必须将复制的内容写入私人粘贴板。

我如何将复制的字符串写入粘贴板。我得到的参数是 id 类型。如果我将它转换为 NSString,它将不正确,因为它是调用此方法(UIMenuController)的发送者。