gpt4 book ai didi

ios - 如何指向 allocWithZone : to a subclass under ARC (NOT a singleton!)

转载 作者:行者123 更新时间:2023-12-01 18:58:07 25 4
gpt4 key购买 nike

我见过一些类似于这个的 SO 问题,但它们都涉及单例,答案都是(正确地)“不要那样做,改用 dispatch_once()”。

在我的特定实例中,我没有制作单例,我需要父类(super class)的 allocWithZone:返回我的子类的一个实例。

我想做的是:我想对我不拥有的现有库进行扩展。而不是在类别中做一堆行为——如果我覆盖现有行为,它甚至无法正常工作,因为没有定义调用许多相同签名方法中的哪一个——我希望它是,当有人包括我的(非常小的)类别时,然后调用

LibObject *myObj = [[LibObject alloc] init];

相反,他们回来了,就好像他们打过电话一样
LibObject *myObj = [[MyLibObjSubclass alloc] init];

在哪里 LibrarySubclass是我正在创建的子类。特别是,作为 LibObject 子类的所有库对象,我希望它们成为 MyLibObjSubclass 的子类.

我已经搞乱了调酒和类别以及我能想到的所有其他事情,但我总是遇到两个问题之一:要么
  • [MyLibObjSubclass alloc] 的无限递归之后,我最终崩溃了调用[LibObject alloc]调用[MyLibObjSubclass alloc]等,或
  • 属于 LibObject 子类的所有内容,而不是 MyLibObjSubclass 的子类,有了它的新行为,它只是一个 MyLibObjSubclass ,没有任何额外的行为。

  • 对于第二个问题,例如,假设我试图覆盖所有 UIView -s 为 MyView -s,其中 MyViewUIView 的子类.问题是,当我尝试分类时(作为 UIView+MyShim 的一部分),那么这一行:
    UILabel *label = [[UILabel alloc] init];

    而不是返回 UILabel这是 MyView -> UIView -> UIResponder -> NSObject 的子类,它只返回一个 MyView例如,其中不包含 text属性(property),所以所有 UILabel -s 坏了。

    所以我的问题是:我该如何做我想做的事?

    谢谢!

    最佳答案

    听起来您想从中修改类层次结构:

    CCResponder
    └─ CCNode
    ├─ CCControl
    └─ CCSprite

    对此:
    CCResponder
    └─ MyResponder
    └─ CCNode
    ├─ CCControl
    └─ CCSprite

    由于 class_setSuperclass已弃用,没有受支持的方法可以在运行时进行更改。

    ( 注意: 是的,这正是我希望做的。~Olie。)

    是否考虑过只修改 Cocos2D 源代码?短期来看,这应该是最简单的方法。如果您需要的足够通用,也许您可​​以将您的更改合并到上游。或者,也许您可​​以添加将被上游接受的钩子(Hook),并使用这些钩子(Hook)来做您需要的事情。

    如果您将代码保存在 git 中,那么我建议使用 git-subtree 扩展将 Cocos2D 源代码导入项目的存储库。这使得跟踪您对 Cocos2D 的本地更改并在您想要导入更新版本时重新应用它们变得非常容易。

    如果这对你不起作用,我认为你应该把它吸起来,并在你想要改变其行为的方法上使用 swizzling。

    如果你是一个贪吃的惩罚者,你可以为每个 CCResponder 创建一个新的子类。子类,在运行时按需提供。你最终会得到这样的层次结构:
    CCResponder
    └─ CCNode
    ├─ CCControl
    │ └─ hacked_CCControl
    └─ CCSprite
    └─ hacked_CCSprite

    (我知道 CCControl 不是你可能直接实例化的东西,但让我们假装吧。)

    我认为这是可能的,但相当复杂。要做到这一点,调酒 +[CCResponder alloc]与(您自己的) +[CCResponder allocHack] .你会实现这样的事情:
    static Class createHackedClassForClass(Class originalClass) {
    NSString *name = [@"hacked_" stringByAppendingString:NSStringFromClass(originalClass)];
    Class hackedClass = objc_allocateClassPair(originalClass, name.UTF8String, 0);

    // Here add methods as necessary to hackedClass using class_addMethod.

    objc_registerClassPair(hackedClass);
    return hackedClass;
    }

    + (void)allocHack {
    static NSMutableDictionary *hackedClassForClass = [NSMutableDictionary dictionary];
    Class hackedClass = hackedClassForClass[self];
    if (hackedClass == nil) {
    hackedClass = createHackedClassForClass(self);
    hackedClassForClass[self] = hackedClass;
    }
    return class_createInstance(hackedClass, 0);
    }

    这个我没试过,不知道有没有什么大问题。它至少会使调试变得比仅仅修改 Cocos2D 源代码更难。

    关于ios - 如何指向 allocWithZone : to a subclass under ARC (NOT a singleton!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25145717/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com