在Objective-C中创建匿名委托对象

时间:2023-01-15 18:20:19

Cocoa uses delegates extensively to provide (among other things) callback methods for asynchronous operations. However, I personally hate the delegate model and how it pollutes the current class with handlers for very specific child operations. UIAlertView is a perfect example.

Cocoa广泛使用委托来提供(除其他外)异步操作的回调方法。但是,我个人讨厌委托模型以及它如何使用处理程序对非常特定的子操作污染当前类。 UIAlertView就是一个很好的例子。

Therefore, I'm wondering if it's possible to simply create an anonymous delegate object that meets the requirements of a delegate protocol (such as UIAlertViewDelegate) via blocks and pass this anonymous object wherever a delegate reference is expected.

因此,我想知道是否可以通过块简单地创建满足委托协议(例如UIAlertViewDelegate)要求的匿名委托对象,并在需要委托引用的任何地方传递此匿名对象。

I imagine something like so:

我想象的是:

id myDelegate = @{
    alertView:alertView didDismissWithButtonIndex:index = ^ {
        ...
    }
};

UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:... message:... delegate:myDelegate cancelButtonTitle:... otherButtonTitles:...;
[alertView show];

I've heard Objective-C has some good dynamic language features but I don't know how to simply add a method/selector to an object. Can this be done in a relatively straightforward manner?

我听说Objective-C有一些很好的动态语言功能,但我不知道如何简单地向对象添加方法/选择器。这可以以相对简单的方式完成吗?

4 个解决方案

#1


5  

Yes, the language features you mention are exposed via the objective-c runtime, although there's no built-in facility to dynamically create delegate classes and the runtime api is not the friendliest of things.

是的,您提到的语言功能是通过objective-c运行时公开的,尽管没有内置工具可以动态创建委托类,而运行时api并不是最友好的。

There is a library called A2DynamicDelegate, which does exactly what you're talking about. I haven't used it, but it may be worth investigating.

有一个名为A2DynamicDelegate的库,它正是您正在谈论的内容。我没有使用它,但它可能值得调查。

EDIT: A problem with this approach is that delegates are not retained, so you'll need to either keep a strong reference somewhere else, or an add an associative reference to the UIAlertView. You may find that all this fuss isn't worth it and just adding an extra method to your view controller works better (you can conform to the delegate protocol in a class extension to avoid polluting your interface).

编辑:这种方法的一个问题是不保留委托,因此您需要在其他地方保留强引用,或者添加UIAlertView的关联引用。您可能会发现所有这些大惊小怪都不值得,只需在视图控制器中添加额外的方法就可以更好地工作(您可以在类扩展中符合委托协议以避免污染您的界面)。

#2


3  

One option is to write a class which wraps your blocks for the individual methods of the delegate protocol into a delegate object. For details see this answer.

一种选择是编写一个类,该类将用于委托协议的各个方法的块包装到委托对象中。详情请见此答案。

#3


2  

You should consider using a category that adds block support to UIAlertView, which seems to address your use case. UIAlertView-Blocks is my favorite one although there are many others.

您应该考虑使用一个为UIAlertView添加块支持的类别,这似乎可以解决您的用例。 UIAlertView-Blocks是我最喜欢的,虽然还有很多其他的。

#4


0  

If you want to use blocks with a delegate-based API, you'll have to do some subclassing. For example, see PSAlertView, which subclasses UIAlertView to provide a block-based API.

如果要使用具有基于委托的API的块,则必须进行一些子类化。例如,请参阅PSAlertView,它是UIAlertView的子类,以提供基于块的API。

#1


5  

Yes, the language features you mention are exposed via the objective-c runtime, although there's no built-in facility to dynamically create delegate classes and the runtime api is not the friendliest of things.

是的,您提到的语言功能是通过objective-c运行时公开的,尽管没有内置工具可以动态创建委托类,而运行时api并不是最友好的。

There is a library called A2DynamicDelegate, which does exactly what you're talking about. I haven't used it, but it may be worth investigating.

有一个名为A2DynamicDelegate的库,它正是您正在谈论的内容。我没有使用它,但它可能值得调查。

EDIT: A problem with this approach is that delegates are not retained, so you'll need to either keep a strong reference somewhere else, or an add an associative reference to the UIAlertView. You may find that all this fuss isn't worth it and just adding an extra method to your view controller works better (you can conform to the delegate protocol in a class extension to avoid polluting your interface).

编辑:这种方法的一个问题是不保留委托,因此您需要在其他地方保留强引用,或者添加UIAlertView的关联引用。您可能会发现所有这些大惊小怪都不值得,只需在视图控制器中添加额外的方法就可以更好地工作(您可以在类扩展中符合委托协议以避免污染您的界面)。

#2


3  

One option is to write a class which wraps your blocks for the individual methods of the delegate protocol into a delegate object. For details see this answer.

一种选择是编写一个类,该类将用于委托协议的各个方法的块包装到委托对象中。详情请见此答案。

#3


2  

You should consider using a category that adds block support to UIAlertView, which seems to address your use case. UIAlertView-Blocks is my favorite one although there are many others.

您应该考虑使用一个为UIAlertView添加块支持的类别,这似乎可以解决您的用例。 UIAlertView-Blocks是我最喜欢的,虽然还有很多其他的。

#4


0  

If you want to use blocks with a delegate-based API, you'll have to do some subclassing. For example, see PSAlertView, which subclasses UIAlertView to provide a block-based API.

如果要使用具有基于委托的API的块,则必须进行一些子类化。例如,请参阅PSAlertView,它是UIAlertView的子类,以提供基于块的API。