2010-09-22 81 views
16

我想在Objective-C中的类方法中设置对象的委托。伪代码:Objective-C相当于类方法中的Java匿名类

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

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

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

+0

可能重复http://stackoverflow.com/questions/766475/anonymous-delegate-implementation-in- objective-c) – 2010-09-22 15:11:38

+0

@Dave DeLong澄清标题以区别于该问题。在这种情况下,上下文是一种静态方法。 – hpique 2010-09-22 15:27:03

+0

上下文无关紧要。你必须提供一个对象('id')作为委托,另一个问题很明显地回答说Objective-C(尚未)中没有匿名类,所以你将不得不使用正常的对象。 – 2010-09-22 15:31:53

回答

13

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

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

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

或者,发送委托消息的方法可以检查一个零委托,并在这种情况下做一些明智的事情。

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

+0

谢谢JeremyP!所以基本上在这种情况下,我可以在实现文件中定义一个临时类,在类消息中创建一个实例并将其指定为委托。这是正确的吗? – hpique 2010-09-22 16:03:48

+0

在这种情况下,这可能是正确的做法。 – JeremyP 2010-09-23 08:49:11

16

正如JeremyP所说的,目标C中没有匿名类,就像在Java中一样。

但是在Java中,,匿名类主要用于实现单一方法接口或我们也称之为功能接口。

我们这样做是为了避免实现接口一类只是这是最常用的听众,观察员和事件处理一个方法实现。

这是因为在Java中缺乏匿名一流的功能主要是完成(之前的版本8和Lambda项目)。

目标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 
              }]; 
1

匿名类可以与库来实现。几个月前,我一直在研究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(MM_REUSE, *)实例。类将仅在首次执行时创建,并在默认情况下重用,但您可以通过调用MM_CREATE_CLASS_ALWAYS(*)MM_CREATE_ALWAYS(*)来避免重复使用。

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

我喜欢第二种方式,不要在运行时创建很多类。恕我直言,它更安全,足够强大。

要使用该库只是:

pod 'MMMutableMethods', :git => 'https://github.com/k06a/MMMutableMethods' 
([?在Objective-C匿名委托执行]的