标签: swizzling

Objective C中方法调配的危险是什么?

我听说有人说方法调整是一种危险的做法.即使是名字调整也会让人觉得这有点像作弊.

方法Swizzling正在修改映射,以便调用选择器A实际上将调用实现B.这样做的一个用途是扩展封闭源类的行为.

我们能否将风险正式化,以便任何决定是否使用调酒的人都可以做出明智的决定是否值得他们尝试做什么.

例如

  • 命名冲突:如果该类稍后扩展其功能以包括您添加的方法名称,则会导致大量问题.通过明智地命名混合方法来降低风险.

objective-c swizzling ios

232
推荐指数
5
解决办法
4万
查看次数

如何实现swift swift 3.0的方法?

如何在Swift 3.0中实现方法调配?

我已经阅读了关于它的nshipster文章,但是在这个代码的块中

struct Static {
    static var token: dispatch_once_t = 0
}
Run Code Online (Sandbox Code Playgroud)

编译器给我一个错误

dispatch_once_t在Swift中不可用:改为使用延迟初始化的全局变量

xcode swizzling ios swift swift3

37
推荐指数
3
解决办法
2万
查看次数

如何在iOS上调整类方法?

方法调配对于实例方法非常有用.现在,我需要调整一个类方法.知道怎么做吗?

试过这个,但它不起作用:

void SwizzleClassMethod(Class c, SEL orig, SEL new) {

Method origMethod = class_getClassMethod(c, orig);
Method newMethod = class_getClassMethod(c, new);

if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
    class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
    method_exchangeImplementations(origMethod, newMethod);
}
Run Code Online (Sandbox Code Playgroud)

iphone objective-c swizzling ios

31
推荐指数
1
解决办法
2万
查看次数

方法在iPhone设备上Swizzle

我尝试了JRSwizzle和MethodSwizzle.他们在模拟器上编译得很好,但是当我尝试编译Device(3.x)时会抛出一堆错误

有没有人在iPhone上乱跑?什么诀窍?

TIA

iphone objective-c swizzling

25
推荐指数
1
解决办法
2万
查看次数

App Store - 方法调整合法性

在App Store上是否存在关于方法调查的最新信息是合法/非法的?

我能找到的唯一数据点是一段时间后的Three20框架重组,从这个通知开始:

您当前发布到App Store的应用程序xxx正在使用method_exchangeImplementations将Apple提供的API的实现与您自己的实现交换.由于即将发生的更改,应用程序中的此行为可能会导致崩溃或导致iPhone OS 4.0上的用户数据丢失.

xxx使用method_exchangeImplementations与您的方法ttdealloc交换dealloc的实现.它还用你的方法popViewControllerAnimated2:交换方法popViewControllerAnimated:的实现.

请立即解决此问题,并将新二进制文件上传到iTunes Connect.如果我们认为这样做是谨慎或必要的,我们可能会删除您的申请.


当我在搜索时,我可以找到关于调配和应用程序商店的每个最近的对话似乎都引用了同样的Three20事件.通知似乎非常具体,我想知道问题是否是Three20所做的更改或者method_exchangeImplementations被普遍禁止的具体更改问题.

关于是否允许这种做法,还有其他数据吗?在商店中是否有任何使用应用程序的应用程序的开发人员?

谢谢!

objective-c app-store swizzling ios

21
推荐指数
1
解决办法
4643
查看次数

Swift函数调配/运行时

在Swift之前,在Objective-C中,我会在类中调用或挂钩方法<objc/runtime.h>.

如果有人有任何关于修改Swift的运行时和挂钩函数的信息,比如CydiaSubstrate和其他帮助这个领域的库,请通知我.

runtime swizzling swift

20
推荐指数
3
解决办法
2万
查看次数

现在Swift已经弃用它,是否有替代macOS中的initialize()?

Objective-C声明了一个类函数initialize(),它在每个类使用之前运行一次.它经常被用作交换方法实现(混合)等的入口点.它的使用在Swift 3.1中被弃用.

这就是我以前做的事情:

extension NSView {
    public override class func initialize() {
        // This is called on class init and before `applicationDidFinishLaunching`
    }
}
Run Code Online (Sandbox Code Playgroud)

如果没有,我怎么能做同样的事情initialize

我需要它用于框架,所以要求在AppDelegate中调用一些东西是不行的.我之前需要它applicationDidFinishLaunching.

我非常喜欢这个解决方案.这正是我正在寻找的,但它适用于iOS.我需要它用于macOS.有人可以推荐一个macOS版本吗?

具体来说,我需要相当于此,但对于macOS:

extension UIApplication {
    private static let runOnce: Void = {
        // This is called before `applicationDidFinishLaunching`
    }()

    override open var next: UIResponder? {
        UIApplication.runOnce
        return super.next
    }
}
Run Code Online (Sandbox Code Playgroud)

我试过覆盖各种属性但NSApplication没有成功.

解决方案需要纯粹的Swift.没有Objective-C.

macos swizzling swift

18
推荐指数
2
解决办法
1245
查看次数

调整单个实例,而不是类

我在NSObject上有一个类别应该是这样的东西.当我在一个对象上调用它时,我想覆盖它的dealloc方法来进行一些清理.

我想用方法调配来做,但无法弄清楚如何.我发现的唯一例子是关于如何替换整个类的方法实现(在我的例子中,它将覆盖所有NSObjects的dealloc - 我不想这样做).

我想覆盖NSObject的特定实例的dealloc方法.

@interface NSObject(MyCategory)
-(void)test;
@end

@implementation NSObject(MyCategory)
-(void)newDealloc
{
  // do some cleanup here
  [self dealloc]; // call actual dealloc method
}
-(void)test
{
  IMP orig=[self methodForSelector:@selector(dealloc)];
  IMP repl=[self methodForSelector:@selector(newDealloc)];
  if (...)   // 'test' might be called several times, this replacement should happen only on the first call
  {
     method_exchangeImplementations(..., ...);
  }
}
@end
Run Code Online (Sandbox Code Playgroud)

methods objective-c categories swizzling ios

17
推荐指数
2
解决办法
5224
查看次数

如何实现方法调配?

我试图使用SIMBL修改程序的行为(我没有它的来源).我使用了类转储,发现我需要覆盖一个实例方法

此方法位于名为controller的类中.我需要做的就是获得参数arg1,就是这样.也许NSLog它或发布通知...我读到了Objective-c中的方法调配但我怎么能用它?我需要引用我没有的课程MessageController.

谢谢!

methods cocoa objective-c simbl swizzling

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

从 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
查看次数