【问题标题】:Is it possible to declare an Objective-C method outside a class?是否可以在类之外声明一个 Objective-C 方法?
【发布时间】:2012-02-24 17:35:42
【问题描述】:

我知道你可以在一个类之外声明一个 C 函数,但是是否可以在一个类之外声明一个 Objective-C 方法?

例子:

// Works
void printHelloC()
{
    NSLog(@"Hello.");
}

// Error
-(void) printHelloOC
{
    NSLog(@"Hello.");
}

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        printHelloC();
        [self printHelloOC];// 'self' obviously would not work but you get the idea
    }
    return 0;
}

【问题讨论】:

    标签: objective-c c methods


    【解决方案1】:

    没有关联类的方法是一个没有意义的概念。正如您所指出的,函数很好。

    【讨论】:

    • 不一定正确。你可以有一个选择器来执行特定代码,而与对象是什么无关,只要它执行特定任务。这就是协议背后的原因。
    • @RichardJ.RossIII - 做你描述的事情,你肯定会在NSObject上定义一个category
    • @CRD 不一定,您可以通过方法添加来做同样的事情(见我的回答)。这基本上是一种更复杂的方式来完成类别的工作。
    【解决方案2】:

    您可以为此使用一个类别

    作为实例方法:

    @interface NSObject (MONStuff)
    - (void)printHelloOC;
    @end
    
    @implementation NSObject (MONStuff)
    - (void)printHelloOC
    {
      NSLog(@"Hello.");
    }
    @end
    
    // in use:
    
    NSObject * obj = ...;
    [obj printHelloOC];
    

    作为类方法:

    @interface NSObject (MONStuff)
    + (void)printHelloOC;
    @end
    
    @implementation NSObject (MONStuff)
    + (void)printHelloOC
    {
      NSLog(@"Hello.");
    }
    @end
    
    // in use:
    
    [NSObject printHelloOC];
    

    当然,您必须将它与一个类相关联 - 所以它与您发布的完全不一样,但它是一个与正式类声明分开的紧密定义+声明。

    【讨论】:

    • 一个类别只是扩展了一个类——根据定义,该类别中声明的任何方法都在一个类中......
    • 您的新方法是NSString 方法。那不是在课堂之外 - 那是 inside NSString!
    • +1。类别使用类外部编写的方法扩展类。毕竟,这就是使用类别的全部目的
    • 没错,但这不是 OP 所要求的。
    • 谢谢亚历克斯。 @Carl 是的,我发布了该类别,因为这是扩展现有类的一种常用方法。你想以迂腐的方式回答这个问题,还是以实际的方式回答这个问题?在许多情况下,这种“外部”方法是实现您需要的实用方法。有些人会觉得它很有帮助。
    【解决方案3】:

    Objective c 函数总是与一个类相关联。如果你的意思是你想使用一个objective-c函数而不实例化一个类,你当然可以写一个类方法(注意加号而不是通常的连字符)

    @interface Test
    
    + (void)aClassMethod;
    
    @end
    

    那么你可以通过调用来调用它

    [Test aClassMethod];
    

    【讨论】:

    • 并非总是如此。例如,如果您使用方法调配,您可以将一个函数添加到具有多个选择器的多个类中!
    • 也许...但是方法混合是一个非常先进的概念,如果不仔细考虑,绝对不能这样做。
    • 这并不复杂,您只需包含运行时,创建您的函数,然后使用选择器将方法添加到类中。这不需要火箭科学家来做,交换方法实现同样容易。
    【解决方案4】:

    这取决于。您可以通过在运行时添加方法来做类似的事情:

    #import <objc/runtime.h>
    
    void myCustomMethod(id self, SEL _cmd, id arg1, id arg2)
    {
        NSLog(@"This is a test, arg1: %@, arg2: %@", arg1, arg2);
    }
    
    int main(int argc, char *argv[])
    {
        Class NSObjClass = [NSObject class];
    
        class_addMethod(NSObjClass, @selector(myNewMethod::), (IMP) myCustomMethod, "v@:@@");
    
        NSObject myObject = [NSObject new];
    
        [myObject myNewMethod:@"Hi" :@"There"];
    
        [myObject release];
    
        return 0;
    }
    

    但这只是@class 构造之外的内容,它实际上只是掩盖了一个类别发生的事情。

    【讨论】:

    • 很好的答案,但是您的方法名称有点用词不当,因为它实际上是一种方法而不是选择器
    【解决方案5】:

    不,这是不可能的——您需要使用全局 C 函数或类 (+) 方法。

    【讨论】:

    • 有可能,Objective-C 运行时允许您在程序执行时向类添加方法。它甚至允许您创建全新的类。您可以定义一个 Objective-C 方法实现,然后将该方法与一个类和一个选择器相关联。
    • 是的,确实可以动态创建类。然而,这不是问题。问题是是否可以定义和执行 Objective-C 方法以及全局 C 函数(或者说,全局范围的 JavaScript 闭包)。这不可能。 Objective-C 方法必须定义为类的一部分(类或实例范围)。
    猜你喜欢
    • 2010-10-13
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2016-11-11
    • 2011-01-10
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多