Objective-C相当于Java';类方法中的匿名类

Objective-C相当于Java';类方法中的匿名类,java,objective-c,delegates,anonymous-types,Java,Objective C,Delegates,Anonymous Types,我想在Objective-C中的类方法中设置对象的委托。伪代码: + (ClassWithDelegate*) myStaticMethod { if (myObject == nil) { myObject = [[ClassWithDelegate alloc] init]; // myObject.delegate = ? } return myObject; } 在Java中,我只需创建一个实现委托协议的匿名类。如何在Object

我想在Objective-C中的类方法中设置对象的委托。伪代码:

+ (ClassWithDelegate*) myStaticMethod {
    if (myObject == nil) {
        myObject = [[ClassWithDelegate alloc] init];
        // myObject.delegate = ?
    }
    return myObject;
}
在Java中,我只需创建一个实现委托协议的匿名类。如何在Objective-C中执行类似操作


基本上,我希望避免创建单独的类(和文件)来实现简单的委托协议。

Objective-C中目前没有匿名类

通常可以使用已存在的对象。例如,对于NSTableViewDataSource,可以实现文档或视图控制器中的方法,并将其作为委托传递

或者,您可以让对象本身实现协议,并在默认情况下使其成为自己的委托

或者,发送委托消息的方法可以检查nil委托,并在这种情况下执行一些合理的操作


或者,您可以在创建需要委托的对象的实现文件中声明并定义一个类。

正如JeremyP正确地说的那样,Objective C中没有像Java中那样的匿名类

但在Java中,匿名类主要用于实现单个方法接口或我们称之为函数接口的接口

我们这样做是为了避免只为一个方法实现而在类**中实现接口**,该方法最常用于侦听器、观察器和事件处理程序

这主要是因为**缺少Java中的匿名第一类函数(在版本8和project lambda之前)

Objective C有一种称为blocks的东西,您可以直接传递一个包含单个方法实现的块,而不是一个封装它的空类

示例:

匿名类在Java中的应用

//Functional interface
interface SomethingHandler 
{
  void handle(Object argument);
}

//a method that accepts the handler in some other class
class SomeOtherClass
{ 
  void doSomethingWithCompletionHandler(SomethingHandler h){
      // do the work that may consume some time in a separate thread may be.
      // when work is done call the handler with the result which could be any object
      h.handler(result);
  };
}

// Somewhere else in some other class, in some other code
// passing the handler after instantiating someObj as an object of SomeOtherClass which can use the handler as needed
SomeOtherClass someObj = new SomeOtherClass();
someObj.doSomethingWithCompletionHandler( new SomethingHandler()
                        {
                              void handle(Object argument)
                              {
                                // handle the event using the argument
                              }
                         });
在目标C中

// declare the handler block 
typedef void (^SomethingHandler)(id argument){}

// this interface is different than Java interface  which are similar to Protocols
@interface SomeOtherClass
 -(void)doSomethingWithCompletionHandler:(SomethingHandler)h;
@end

@implementation SomeOtherClass
 -(void)doSomethingWithCompletionHandler:(SomethingHandler)h
 {
          // do the work that may consume some time in a separate thread may be.
          // when work is done call the handler with the result which could be any object
          h(result);
 }

@end

  // passing the handler after instantiating someObj as an object of SomeOtherClass which can use the handler as needed

SomeOtherClass* someObj = [[SomeOtherClass alloc] init]; // ARC :)

[someObj doSomethingWithCompletionHandler:^(id argument)
                                            {
                                               // handle the event using the argument
                                            }];

匿名类可以通过库实现。几个月前,我一直在研究
MMMutableMethods
fork,以改进旧的实现(与作者讨论),并添加我自己的机制,而无需任何obj-c运行时操作

A.第一种机制用于obj-c运行时类的创建:

MM_CREATE(MM_REUSE,^(Class class){
    [class addMethod:@selector(onResultWithId:)
        fromProtocol:@protocol(AMCommandCallback)
            blockImp:^(id this,id res){
                NSLog(@"onResultWithId: %@",res);
            }];
    [class addMethod:@selector(onErrorWithJavaLangException:)
        fromProtocol:@protocol(AMCommandCallback)
            blockImp:^(id this,JavaLangException *e){
                NSLog(@"onErrorWithJavaLangException: %@",e);
            }];
})
B.第二种机制用于简单的消息转发实现:

MM_ANON(^(MMAnonymousClass *anon){
    [anon addMethod:@selector(onResultWithId:)
       fromProtocol:@protocol(AMCommandCallback)
           blockImp:^(id this,id res){
               NSLog(@"onResultWithId: %@",res);
           }];
    [anon addMethod:@selector(onErrorWithJavaLangException:)
       fromProtocol:@protocol(AMCommandCallback)
           blockImp:^(id this,JavaLangException *e){
               NSLog(@"onErrorWithJavaLangException: %@",e);
           }];
})
第一个是在运行时创建新的obc-j类,它允许您创建类
MM\u create\u CLASS(MM\u REUSE,*)
,并直接使用
MM\u create(MM\u REUSE,*)创建实例。类将仅在第一次执行时创建并默认重用,但您可以通过调用
MM\u CREATE\u CLASS\u ALWAYS(*)和
MM\u CREATE\u ALWAYS(*)来避免重用

第二种机制不创建任何运行时实例,只需记住选择器的块并将方法调用转发给它们

我更喜欢第二种方法,即不要在运行时创建很多类。依我看,它安全多了,而且足够强大

要使用此库,请执行以下操作:

pod 'MMMutableMethods', :git => 'https://github.com/k06a/MMMutableMethods'

可能重复的@Dave DeLong澄清了标题,以区别于该问题。在这种情况下,上下文是一个静态方法。上下文并不重要。您必须提供一个对象(
id
)作为委托,而另一个问题非常清楚地回答了Objective-C中不存在匿名类这一问题,因此,您必须使用普通对象。Objective-C中没有静态方法。有实例消息和类消息。@Dave DeLong很可能我的问题措词不当,但我不认为它们是同一个问题。是的,在Obj-C中没有匿名类。但是我的问题是:在Obj-C类消息中最好的方法是什么?匿名类允许我在Java静态方法中做什么?谢谢JeremyP!因此,基本上在本例中,我可以在实现文件中定义一个特殊类,在类消息中创建一个实例,并将其分配为委托。是这样吗?