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

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

+ (ClassWithDelegate*) myStaticMethod { if (myObject == nil) { myObject = [[ClassWithDelegate alloc] init]; // myObject.delegate = ? } return myObject; } 

在Java中,我只需创建一个实现委托协议的匿名类。 如何在Objective-C中做类似的事情?

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

Objective-C中目前没有匿名类。

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

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

或者发送委托消息的方法可以检查nil委托,并在那种情况下做一些合理的事情。

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

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

但在Java中,匿名类主要用于实现单个方法接口或我们也称为function接口。

我们这样做是为了避免必须在类**中实现接口**只是为了一个最常用于监听器,观察者和事件处理程序的方法实现。

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

Objective C有一个叫做块的东西,你可以直接传递一个包含该单个方法实现的块,而不是一个包含它的空类。

例:

在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运行时操作。

https://github.com/k06a/MMMutableMethods

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_CREATE_CLASS(MM_REUSE, *)创建类MM_CREATE_CLASS(MM_REUSE, *)和直接实例。 类将仅在第一次执行时创建并在默认情况下重用,但您可以通过调用MM_CREATE_CLASS_ALWAYS(*)MM_CREATE_ALWAYS(*)来避免重用。

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

我倾向于第二种方式不在运行时创建很多类。 恕我直言,它更安全,更强大。

要使用这个库:

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