网络图片的获取和显示的方法

来源:互联网 发布:python xml dom 编辑:程序博客网 时间:2024/04/29 23:42

请求网络图片主要有两种方式,第一种是使用NSData的静态方法dataWithContentsOfURL或者对象的初始化方法initWithContentsOfURL来实现。其实现代码如下:

-(void)viewDidLoad{

   [super viewDidLoad];

   NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://img.baidu.com/hi/img/ihome/logo.gif"]];

   UIImage *img=[UIImage imageWithData:data];

   UIImageView *imgView=[[UIImageView alloc] initWithImage:img];

   [self.view addSubview:imgView];

   [imgView release];

}

       以上代码就是通过NSData加载了一张网络图片并由UIImageView显示到视图中。整个过程非常简单,但是上面所写的代码是一个同步的过程,也就是说如果图片尚未加载完成是不会执行程序的下一步的。如果想要加载的图片非常大,那么这个程序运行的时候还一直等待图片加载,在这个过程中用户是无法操作任何东西的。这样的话对于用户体验来说是非常不好的,因此,为了解决这样的问题可以采用异线程的方式进行。在原来的代码基础上修改为如下形式:

-(void)loadImage:(NSString *)url{

   NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:url]];

   UIImage *img=[UIImage imageWithData:data];

   _imgView.image=img;

}

-(void)viewDidLoad{

   _imgView=[[UIImageView alloc] initWithFrame:CGRectMake(0.0,0.0,100.0,100.0)];

   [self.view addSubview:_imgView];

   [_imgView release];

   //创建线程

   NSThread *thread=[[[NSThread alloc] initWithTarget:self selector:@selector(loadImage:) object:@"http://img.baidu.com/hi/img/ihome/logo.gif"] autorelease];

   [thread start];

}

       上面的方法基本上能解决大部分问题,但是如果想要在加载图片的时候知道加载图片的进度、加载的图片是否成功加载还是加载失败了,这些细化的操作则要使用我下面所说的第二种方法,使用NSURLRequestNSURLConnection来加载图片。费用少说了先来代码:

-(void)viewDidLoad{

    _imgView=[[UIImageView alloc] initWithFrame:CGRectMake(0.0,0.0,100.0,100.0)];

   [self.view addSubview:_imgView];

   [_imgView release];

 

   NSURLRequest *request=[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://img.baidu.com/hi/img/ihome/logo.gif"];

   NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];

   [conn start];

   [conn release];

   [request release];

 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{

   //保存接收到的响应对象,以便响应完毕后的状态。    

   _response=[response retain];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

  //_dataNSMutableData类型的私有属性,用于保存从网络上接收到的数据。   

  //也可以从此委托中获取到图片加载的进度。 

  [_data appendData:data];

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{

   //请求异常,在此可以进行出错后的操作,如给UIImageView设置一张默认的图片等。    

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{

    //加载成功,在此的加载成功并不代表图片加载成功,需要判断HTTP返回状态。

   NSHTTPURLResponse *response=(NSHTTPURLResponse *)_response; 

   if([response statusCode]/100==2){

      //请求成功

      UIImage *img=[UIImage imageWithData:_data];

      _imgView.image=img;

  }

}

       以上代码就是一个完整的请求过程,不过程序中有不完善的地方,如没有释放需要释放的对象以及请求出错后的处理等,因为这是例子所以这些就忽略掉了。虽然整个过程有一点的复杂不过他却可以对要加载的图片进行更细微的控制这是NSData不能取代的。

       最后在这里需要注意一点问题,如果你是在IOS4.3以上的机器上实现第二种方法的话,那么直接把接收到的数据来初始化UIImage的话,在UIImageView中显示出来的图片是黑乎乎一遍的。但是在IOS4.3以下版本却不存在。于是我就尝试把用接收数据初始化的照片保存到相册,但它却提示无任何照片数据写入。这时候我就在想是不是接收数据的NSMutableData的数据指针已经指向了数据的最后了引起的。因此,我将接收数据的NSData赋予一个新的NSData后发现问题解决了。代码修改如下:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{

    //加载成功,在此的加载成功并不代表图片加载成功,需要判断HTTP返回状态。

   NSHTTPURLResponse *response=(NSHTTPURLResponse *)_response; 

   if([response statusCode]/100==2){

      //请求成功

      NSData *data=[NDData dataWithData:_data];

      UIImage *img=[UIImage imageWithData:data];

      _imgView.image=img;

  }

}