Objective-C中的块真的有用吗?它们的效用是什么? [英] Are blocks in Objective-C are really useful? What can their utility be?

查看:83
本文介绍了Objective-C中的块真的有用吗?它们的效用是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚阅读了有关块的信息,并且我知道它们只是将信息封装为一种常规方法,但是具有自己的强大引用数据.我想知道可以很好地使用块吗?

I've just read about blocks, and I understood that they just encapsulate information as a normal method, but with their own strong referenced data. I'm wondering what a good use of blocks could be?

推荐答案

这里是将自己应用到我的项目中的块的一种用法;替换委托和协议(在某些情况下).

Here's a use for blocks that applied itself to my project; replacing delegates and protocols (in certain situations).

问题

假设您需要从服务器异步加载数据.您可能有一个需要将PUT放入路径(带有数据)的方法,然后最终在任务完成时将结果发送到方法调用者.

Say you need to asynchronously load data from a server. You might have a method that needs to PUT to a path (with data), and then eventually, when the task is completed, send the results to the method caller.

代理和协议解决方案

这是我们客户端的方法签名,称为AppClient:

Here's our method signature from our client, call it AppClient:

- (void)putToPath:(NSString *)path withData:(id)data;

由于该方法是异步的,因此我们不能在该返回值中包含数据(这意味着它不等待任务完成以完成其他事情,例如运行下一行代码).相反,我们构造了一个协议:

We can't include the data in the return for this method since it's asynchronous (meaning it doesn't wait for the task to be completed to do other things, like run the next line of code). Instead, we construct a protocol:

@protocol AppClientRequestDelegate
- (void)appClient:(AppClient *)appClient didPutToPath:(NSString *)path withData:(id)sentData andReturnedData:(id)recievedData;
@end

然后您的AppClient类将创建一个如下属性:

Then your AppClient class would create a property like so:

@property (weak, nonatomic)id<AppClientRequestDelegate> requestDelegate;

putToPath...方法的调用者会将其AppClient的requestDelegate属性的实例设置为self,并实现该方法,然后使用pathsentData参数验证正确的请求,并执行某些操作-或-other与receivedData参数.

The caller of the putToPath... method would set his instance of AppClient's requestDelegate property to self, and implement the method, then verify the correct request using the path and sentData parameters, and do something-or-other with the receivedData parameter.

我们的呼叫者代码如下:

Our caller's code would look like this:

- (void)syncData:(id)data {
    [self.appClient putPath:@"/posts/9" withData:data];
}

- (void)appClient:(AppClient *)appClient didPutToPath:(NSString *)path withData:(id)sentData andReturnedData:(id)recievedData {
    if (/*path and sentData are right*/) {
        // Do something with recievedData
    }
}

这一切都很好,但是当您在同一路径中有一堆PUT请求时,它很烂,并尝试从协议实现中区分这些请求.我猜您可以在委托方法和putToPath...方法中都添加另一个参数,该参数为每个请求指定一个ID,但这会造成混乱和混乱.

This is all great, but it sucks when you have a bunch of PUT requests to the same path, and try to differentiate the requests from within the protocol implementation. I guess you could add another parameter to both the delegate method and the putToPath... method that specified an id for each request, but that would be messy and confusing.

另一个潜在的问题是,您是否在整个应用程序中广泛使用异步加载;可能会导致大量的委托和协议.

Another potential concern is if you use asynchronous loading widely throughout this app; that could result in a whole lot of delegates and protocols.

阻止解决方案

我们将方法签名扩展为包含一个块:

We extend our method signature to include a block:

- (void)putToPath:(NSString *)path withData:(id)data completion:(void (^)(id returnedData))completion;

该语法确实令人生畏,但它不仅包含协议中的所有信息,而且允许方法的调用者将所有逻辑浓缩为一个方法,从而将在该方法内调用的局部变量引入范围该区块的实现方式.

Granted, this syntax is pretty daunting, but it not only includes all the information from the protocol, but allows the caller of the method to condense all logic into one method, thereby bringing the local variables called within that method into the scope of the block's implementation.

呼叫者的代码现在看起来像这样:

Our caller's code would now look like this:

- (void)syncData:(id)data {
    [self.appClient putToPath:@"/posts/9" withData:data completion:^(id returnedData) {
        // Do something with returnedData
    }];
}

结论

您要求很好地使用块,我相信这是一个很好的块.它可能不适用于您,但是您可以看到它不仅可以减少代码量,而且还使其更具可读性和鲁棒性.

You asked for a nice use of blocks, and I believe this is a pretty nice one; it may not be applicable to you but you can see how it not only cuts down on code mass, but makes it more readable and robust as well.

这篇关于Objective-C中的块真的有用吗?它们的效用是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆