美文网首页
ASIHttpRequest中Block代码块的使用和注意事项

ASIHttpRequest中Block代码块的使用和注意事项

作者: 祥子_HelloWorld | 来源:发表于2019-08-05 00:03 被阅读0次

使用ASIHttpRequest的setCompletionBlock、setFailedBlock时碰到一些诡异的内存泄漏和莫名其妙的行为(如:无法release对象)。

1. 声明ASIHttpRequest时一定要使用__block关键字

__block关键字告诉block不要retain request,这对于防止循环retain非常重要!!因为request总是会retain block

2. 谨慎处理block与对象的关系

当setCompletionBlock/setFailedBlock内部使用对象的instance var时,self会被retain(If you access an instance variable by reference, self is retained;)。所以在request结束前向对象发送release消息不会导致对象的释放(dealloc),亦即:该对象依然可进行所有操作,这将导致诸多你意想不到的结果。

3. 解决第2点的问题

3.1 仔细拿捏block与对象的关系 + 按值的方式访问instance var(If you access an instance variable by value, the variable is retained.)
3.2 不使用block,而使用ASIHttpRequestDelegate

4. 参考资料

4.1 http://allseeing-i.com/ASIHTTPRequest/How-to-use - Using blocks
4.2 Blocks Programming Topics - Object and Block Variables

接口部分:
//
//  LYHASIRequestBlock.h
//  ASIBlockTest
//
//  Created by Charles Leo on 14-7-23.
//  Copyright (c) 2014年 Charles Leo. All rights reserved.
//
 
#import <Foundation/Foundation.h>
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
typedef void (^RequestBlock) (void);
@interface LYHASIRequestBlock : NSObject <ASIHTTPRequestDelegate>
{
    ASIHTTPRequest * getRequest;
    ASIFormDataRequest * postRequest;
    NSURL * url;
    RequestBlock finishBlock;
    RequestBlock failBlock;
    RequestBlock startBlock;
    NSString * requestType;
}
 
//接收到的数据
@property (strong,nonatomic) NSData * receiveData;
//请求完成的block
- (void)didFinishBlock:(RequestBlock)block;
//请求失败的block
- (void)didFailedBlock:(RequestBlock)block;
//请求开始的block
- (void)didStartBlock:(RequestBlock)block;
//取消请求
- (void)cancelRequst;
//get请求方法
- (void)getRequest:(NSString *)getUrl;
//post请求方法
- (void)postRequest:(NSString *)postUrl andKeys:(NSArray *)keyArray andValues:(NSArray *)valueArray;
@end
实现部分:
//
//  LYHASIRequestBlock.m
//  ASIBlockTest
//
//  Created by Charles Leo on 14-7-23.
//  Copyright (c) 2014年 Charles Leo. All rights reserved.
//
 
#import "LYHASIRequestBlock.h"
 
@implementation LYHASIRequestBlock
 
- (void)getRequest:(NSString *)getUrl
{
    requestType = @"GET";
    getRequest  = [[ASIHTTPRequest alloc]initWithURL:[NSURL URLWithString:getUrl]];
    getRequest.delegate = self;
    getRequest.timeOutSeconds = 15;
    [getRequest startAsynchronous];
}
#pragma mark -GET请求的代理方法
//开始请求
- (void)requestStarted:(ASIHTTPRequest *)request
{
    startBlock();
}
//请求完成
- (void)requestFinished:(ASIHTTPRequest *)request
{
    self.receiveData = request.responseData;
    finishBlock();
}
//请求失败
- (void)requestFailed:(ASIHTTPRequest *)request
{
    failBlock();
}
//post请求
-(void)postRequest:(NSString *)postUrl andKeys:(NSArray *)keyArray andValues:(NSArray *)valueArray
{
    postRequest = [[ASIFormDataRequest alloc]initWithURL:[NSURL URLWithString:postUrl]];
    postRequest.timeOutSeconds = 15;
    postRequest.delegate = self;
    for (int i = 0; i<keyArray.count; i++) {
        [postRequest setPostValue:[valueArray objectAtIndex:i] forKey:[keyArray objectAtIndex:i]];
    }
    [postRequest setDidFinishSelector:@selector(didFinishPostRequest:)];
    [postRequest setDidStartSelector:@selector(didStartPostRequest:)];
    [postRequest setDidFailSelector:@selector(didFailPostRequest:)];
    [postRequest startAsynchronous];
}
 
#pragma mark - POST请求的代理方法
//请求开始
- (void)didStartPostRequest:(ASIFormDataRequest *)request
{
    startBlock();
}
//请求完成
- (void)didFinishPostRequest:(ASIFormDataRequest *)request
{
    finishBlock();
}
//请求失败
- (void)didFailPostRequest:(ASIFormDataRequest *)request
{
    failBlock();
}
 
//设置Blocks
//设置开始块
- (void)didStartBlock:(RequestBlock)block
{
    [startBlock release];
    startBlock = [block copy];
}
//设置完成块
-(void)didFinishBlock:(RequestBlock)block
{
    [finishBlock release];
    finishBlock = [block copy];
}
//设置失败块
-(void)didFailedBlock:(RequestBlock)block
{
    [failBlock release];
    failBlock = [block copy];
}
//取消请求
- (void)cancelRequst{
    if ([requestType isEqualToString:@"GET"])
    {
        [getRequest cancel];
    }
    else if([requestType isEqualToString:@"POST"])
    {
        [postRequest cancel];
    }
}
 
-(void)dealloc
{
    [getRequest release];
    [postRequest release];
    [startBlock release];
    [finishBlock release];
    [failBlock release];
    [super dealloc];
}
@end

参考:http://www.cocoachina.com/bbs/read.php?tid=95100
http://code4app.com/snippets/one/%E7%94%A8Block%E5%B0%81%E8%A3%85ASIHttpRequest/5428f5b8933bf0bf118b51d8

相关文章

  • ASIHttpRequest中Block代码块的使用和注意事项

    使用ASIHttpRequest的setCompletionBlock、setFailedBlock时碰到一些诡异...

  • iOS block的使用

    block的使用 Block 又称为“块” 或 “代码块”,作用是用来保存代码。block基本格式: 1、使用ty...

  • ios的block原理

    block:代码块,函数指针和指针 block:使用copy关键字 堆block:@propetry 栈block...

  • Swift3.x - 闭包

    闭包的介绍闭包是自包含的函数代码块、可以在代码中被传递和使用。Swift中的闭包与C和OC中的代码块(Block)...

  • swift-闭包

    闭包是自包含的代码块,可以在代码中被传递和使用。Swift中的闭包与C和Objective-C中代码块(block...

  • Swift 3.0之闭包(Closures)入门和OC bloc

    闭包是自包含的函数代码块,可以在代码中被传递和使用.(参考OC中的Block) 一. 定义闭包或者block 1....

  • iOS技术总结(Block)[整理]

    摘要: . Block代码块结构及几种类型. __block使用.使用block在两个界面中传值问题 官方文档:苹...

  • Block简介和使用

    简介: block是代码块,其本质和变量类似。不同的是代码块存储的数据是一个函数体。block使用最多的是存储代码...

  • Swift3.x 之闭包 ◉•⦿

    ◎ 闭包 闭包: 自包含的函数代码块,可以再代码中被传递和使用. 闭包和OC中的block非常相似 • ...

  • Swift Closure

    Closure是自包含的代码块,可以在代码中传递和使用,类似于OC中的Block。Closure可以捕获或者存储定...

网友评论

      本文标题:ASIHttpRequest中Block代码块的使用和注意事项

      本文链接:https://www.haomeiwen.com/subject/tlojdctx.html