简体   繁体   English

iOS从方法返回块值

[英]iOS return block value from method

How I can return variable "myDoub(for example=65)" out of method and out block ?? 如何从方法和输出块中返回变量“myDoub(例如= 65)”?

- (double)executeRequestUrlString:(NSString *)urlString withBlock:(double (^)(double myDoub))block {
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response,
                                               NSData *data,
                                               NSError *error) {
                                   if (!error){
                                      //data = 65; for example
                                       block(data);
                                   }
                               }];

    return block(data);  // ???????? This NOT work
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    //
    .......
    //
    double myNewDouble =  [self executeRequestUrlString:fullUrlImage withBlock:^double(double myDoub) {
        return myDoub;
    }];

    // how i can get here variable "myDoub=65" ????

}

The fundamental issue is that the network request is running asynchronously (ie the value you want to "return" will simply not be available until well after the method returns), so you cannot use it like you've outlined. 根本问题是网络请求是异步运行的(即,在方法返回之后,您想要“返回”的值将无法使用),因此您无法像您所概述的那样使用它。 The only way you could do that is to make the request synchronous, which is a very bad idea. 你能做到这一点的唯一方法是使请求同步,这是一个非常糟糕的主意。

Instead, you should embrace the asynchronous pattern. 相反,您应该接受异步模式。 Specifically don't try to use the double after executeRequestUrlString method (because you won't have retrieved the value by the time you get there), but rather use it solely within the context of the withBlock block. 具体来说,不要尝试在executeRequestUrlString方法之后使用double (因为到达那里时你不会检索到值),而是仅在withBlock块的上下文中使用它。 So, put all the code contingent on that double inside the block: 所以,把所有代码都放在块double

- (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(double myDoub))block 
{
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response,
                                               NSData *data,
                                               NSError *error) {
                                   if (!error){
                                       double val = ... // extract the double from the `data`, presumably
                                       block(val);
                                   }
                               }];
}    

- (void)viewDidLoad
{
    [super viewDidLoad];

    //
    .......
    //
    [self executeRequestUrlString:fullUrlImage withBlock:^(double myDoub) {
        // put all of your code that requires `myDoub` in here
    }];

    // but because the above is running asynchronously, do not try to use `myDoub` here
}

You are sending an asynchronous request. 您正在发送异步请求。 That means that your block will be executed at some unknown time in the future, when the calling function is long gone. 这意味着当调用函数早已消失时,您的块将在未来的某个未知时间执行。 So the block cannot return anything to the function that is being called. 因此该块不能向被调用的函数返回任何内容。 Consider that a URL request could take long time, say a minute if you are out of luck. 考虑到URL请求可能需要很长时间,如果运气不好,请说一分钟。 And consider that any URL request can go wrong and not succeed at all. 并且考虑到任何URL请求都可能出错并且根本不会成功。

Instead, your block needs to deliver any data that it receives (at some point in the future) to whoever wants to process the data. 相反,您的块需要将其接收的任何数据(在将来的某个时间点)传递给想要处理数据的任何人。 Typically, a block will call something like 通常情况下,一个块会调用类似的东西

dispatch_async (dispatch_get_main_queue, ^ () {
    // Here you can do things in a thread-safe way. 
})); 

It looks like the method you are trying to create just cannot work. 看起来您尝试创建的方法无法正常工作。

if you want to access a variable outside a block you need to add __block prefix 如果要访问块外的变量,则需要添加__block前缀

__block double myDouble

Apple documentation about variables in blocks 有关块中变量的Apple文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM