在xcode 5.0 iPhone中访问同步块内的控件 [英] access the control inside the synchronous block in xcode 5.0 iPhone

查看:44
本文介绍了在xcode 5.0 iPhone中访问同步块内的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是块编程的新手.我正在尝试下载图像并将其显示在我已经在.h文件中设置其属性的图像视图上.据我所知,该类属性只能在因此,我在viewDidload方法中创建了一个imageView"imgVw"图像,目前无法使用self访问它.请在下面找到我的代码.

I am new to blocks programming.I am trying to download an image and display it on an image view whose property i have already made in my .h file.as far as i know the class property can only be accessed in the form of getter/setter inside the block.So i have created an imageView "imgVw" in viewDidload method and am currently unable to access it inside the block using self. Please find below my code.

/*dispatch the queue asynchronously  for non ui related tasks image downloading*/

    void(^downloadimage)(void)=^{

        dispatch_queue_t concurrentqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        dispatch_async(concurrentqueue,^void{

            __block UIImage *image=nil;

            dispatch_sync(concurrentqueue, ^{
            //download image
                NSString *stringUrl=@"http://www.avajava.com/images/avajavalogo.jpg";
                NSURL *url=[NSURL URLWithString:stringUrl];
                NSURLRequest *request=[NSURLRequest requestWithURL:url];

                NSError *error=nil;
                NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
                if(error== nil && data !=nil)
                {
                    image=[UIImage imageWithData:data];
                }
                else if (error!=nil)
                {
                    NSLog(@"Error %@",[error description]);

                }
                else
                {
                    NSLog(@"No data could be downloaded");
                }

            });
            dispatch_sync(dispatch_get_main_queue(), ^{

                /*show the image on main queue*/
                if(image!=nil)
                {
                **/*set image downloaded to imageView imgVw*/
                [[self imgVw] setImage:image];**

                }
                else
                {
                    NSLog(@"image is not downloaded");
                }

            });
        });
    };

推荐答案

您说您已在 viewDidLoad 中创建了图像视图 imgVw ".如果要以编程方式实例化图像视图(而不是将其放入情节提要/NIB中),那很好.如果要以编程方式实例化它,则首先需要与该图像视图相关联的属性,例如:

You say that you "have created an image view imgVw in viewDidLoad". If you want to instantiate the image view programmatically (rather than putting it into your storyboard/NIB), that's fine. If you're going to instantiate it programmatically, you'd first want a property associated for that image view, e.g.:

@property (nonatomic, weak) UIImageView *imgVw;

然后, viewDidLoad 实例化它:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:...]; // instantiate it any way you want
    [self.view addSubview:imageView];                                 // add as subview
    self.imgVw = imageView;                                           // now set your property
}

然后您可以下载图像.

与您的原始问题无关,您的下载代码比所需的要复杂一些.您无需从并发队列调度到并发队列.另外,当您分派到主队列时,可以异步进行.因此,请摆脱该外部 dispatch_async 并执行以下操作:

Unrelated to your original question, your download code is a little more complicated than it needs to be. You don't need to dispatch to your concurrent queue from the concurrent queue. Also, when you dispatch to the main queue, you can do that asynchronously. Thus, get rid of that outer dispatch_async and just do:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    UIImage *image=nil;

    NSString     *stringUrl = @"http://www.avajava.com/images/avajavalogo.jpg";
    NSURL        *url       = [NSURL URLWithString:stringUrl];
    NSURLRequest *request   = [NSURLRequest requestWithURL:url];

    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
    if(error== nil && data !=nil)
    {
        image = [UIImage imageWithData:data];
    }
    else if (error != nil)
    {
        NSLog(@"Error %@",[error description]);
    }
    else
    {
        NSLog(@"No data could be downloaded");
    }

    dispatch_async(dispatch_get_main_queue(), ^{

        if (image != nil)
        {
            self.imgVw.image = image;
        }
        else
        {
            NSLog(@"image is not downloaded");
        }
    });
});

或者,甚至更容易使用 sendAsynchronousRequest ,它消除了另一个 dispatch_async :

Or, even easier, use sendAsynchronousRequest, which eliminates yet another dispatch_async:

NSString     *stringUrl = @"http://www.avajava.com/images/avajavalogo.jpg";
NSURL        *url       = [NSURL URLWithString:stringUrl];
NSURLRequest *request   = [NSURLRequest requestWithURL:url];

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

    if (connectionError == nil && data != nil)
    {
        UIImage *image = [UIImage imageWithData:data];
        if (image != nil)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imgVw.image = image;
            });
        }
        else
        {
            NSLog(@"image is not downloaded");
        }
    }
    else if (connectionError != nil)
    {
        NSLog(@"Error %@",[connectionError description]);
    }
    else
    {
        NSLog(@"No data could be downloaded");
    }
}];


顺便提一句,在您的问题中,您将上述下载代码放在了一个块变量 downloadimage 中.我不清楚您为什么这么做(而不是仅仅定义执行下载的方法).我担心您在考虑做 dispatch_async(queue,downloadimage); 之类的事情,它只会增加另一个冗余的调度级别.但是如果是这样,您可以将其传递给您自己的方法,该方法将直接调用它,那就很好了.您可能想向我们展示如何使用此块变量.


By the way, in your question, you put this above download code in a block variable, downloadimage. I'm unclear why you did that (rather than just defining a method that does the download). I'm worried that you're thinking that you do something like dispatch_async(queue, downloadimage); which only adds yet another redundant level of dispatching. But if it's so you can pass it to you own method that will call it directly, that's fine. You might want to show us how you're using this block variable.

这篇关于在xcode 5.0 iPhone中访问同步块内的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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