【问题标题】:Automatically running a selector on instance creation在实例创建时自动运行选择器
【发布时间】:2013-12-02 05:36:42
【问题描述】:

在 Objective-C 中,有没有办法在每次实例化对象时自动运行特定的选择器? (我知道+initialize,但我需要一个实例方法)。

具体来说,我正在编写一个自定义字符串类(它继承自我自己的根类,具有与NSObject 类似的接口),并且我试图让它与 Objective-C 常量字符串“很好地配合”。为此,我有以下类定义(根据运行时的要求):

// 1) Required Layout
@interface MYConstantString : MYObject {
    //Class isa; inherited from MYObject
    char *c_string;
    unsigned int length;
}

现在,我想通过在类中使用指向 C-struct 的指针来实现我的字符串类(这个“C 对象”已经很好地实现了,所以我基本上只想将它包装在一个 Objective-C 类中)。因此,理想情况下,我的 Objective-C 类应该是这样的:

// 2) Desired Laout
@interface MYConstantString : MYObject {
    // Class isa;
    StringObject *string;
}

然后类和实例方法将使用 StringObject 包装 C 函数调用。

因此,因为我无法获得所需的 ivar 布局 (2),所以我希望绕过所需的 ivar 布局 (1) 来为我工作。例如:

- (void)fixup {
    // Pseudocode
    temp = copystring(c_string);
    c_string = (void *)StringObjectNewWithString(temp); // Fudge pointer
    length = ... // I can do something else with this.
}

那么,回到这个问题,有没有办法自动调用-fixup,而不是每次我写一个Objective-C常量字符串时都必须执行以下操作?

MYConstantString *str = @"Constant string";
[str fixup];

我知道这是一个淫秽的 hack,Objective-C 常量字符串的互操作性对于我需要的东西并不完全重要,但是能够使用 @"" 语法并使代码更“自然”会很好' 目标-C。

【问题讨论】:

    标签: objective-c string objective-c-runtime


    【解决方案1】:

    我猜你遗漏了一个重要的事实:你在构建时使用-fconstant-string-class=MYConstantString 让编译器将你的类用于常量字符串对象 (@"...")。

    鉴于此,没有。有两个重大问题。首先,常量字符串的“实例创建”发生在编译时,而不是运行时。需要布局的原因是编译器什么都不做,只是将字符串的数据布局在数据部分中,并引用isa 指针所在的适当类对象。它不调用任何自定义代码。它甚至不一定在编译时知道这种自定义代码。给定的翻译单元可能不包括常量字符串类。对它的引用在链接时解析。

    其次,常量字符串实例几乎可以肯定地布置在只读数据部分中。很有可能即使在您的问题中手动调用您的 -fixup 方法也会遇到访问冲突,因为您将修改只读内存。

    您应该考虑使用类集群。使MYConstantString 成为抽象基类的一个具体子类。使其符合所需的布局,并按原样使用字符指针和长度变量。如果在各个点翻译成StringObject 会很方便,请在这些点上执行此操作。如果需要,实现其他单独的具体子类以在内部使用 StringObject

    【讨论】:

    • 抱歉,MYConstantString 而不是 NSConstantString。我曾考虑过一个类集群,但我没有考虑过在 StringObject 中进行转换——这可能是获得我需要的东西的最佳方式,谢谢!
    【解决方案2】:
    MYConstantString *str = @"Constant string";
    

    这是行不通的,因为@"..."NSString,这不仅是布局问题,而且是实例大小问题。如果你想要 0-copy 或类似的东西,你需要做的是:

    MYConstantString *str = [MyConstantString stringWithNSString:@"Constant string"];
    

    并让-stringWithNSString: 识别传递的字符串何时是常量(我很确定常量字符串的具体类很容易识别,并且出于向后兼容性的原因可能从未改变过),然后破解它四处抓取指向字节和类似内容的指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 2011-10-15
      • 2010-09-11
      • 2019-02-06
      • 1970-01-01
      相关资源
      最近更新 更多