ios - 启用 ARC 的 AFNetworking 2 后异步内存泄漏

标签 ios objective-c memory-leaks automatic-ref-counting afnetworking-2

我对 iOS 编码还很陌生。我从以前的程序员那里继承了一段代码,将代码分成几段是个好主意。我希望我能让大家理解这一点。

postservice.h 的一部分

@property(nonatomic)SEL ReturnAction;
@property(nonatomic)id  ReturnDelegate;

在 postservice.m 中调用的方法

-(void)Send:(NSString *)Pmethod  Mparams:(NSDictionary *)Mparams Mdelegate:(id)Mdelegate IsSycn:(BOOL)IsSycn ExternalUrl:(BOOL)ExternalUrl{
Murl=[Murl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:Murl]];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    [manager POST:Murl parameters:Mparams success:^(AFHTTPRequestOperation *operation, id responseObject) { 
        NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        //NSLog(@"success %@", string);
            if ([ReturnDelegate respondsToSelector:ReturnAction]) {
                ((void (*)(id, SEL, id))[ReturnDelegate methodForSelector:ReturnAction])(ReturnDelegate, ReturnAction, string);
        }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            //NSLog(@"error %@", error);
            if ([ReturnDelegate respondsToSelector:ReturnAction]) {
                ((void (*)(id, SEL, id))[ReturnDelegate methodForSelector:ReturnAction])(ReturnDelegate, ReturnAction, error);
            }
          }];
}

然后这是从另一个中级类方法调用的,

SE_MidPostService.h 的一部分

@property(nonatomic)SEL FetchCompleted;
@property(nonatomic)SEL FetchFailed;
@property(nonatomic)id  ReturnDelegate;//unsafe_unretained
@property(nonatomic, retain)PostService * service;

SE_MidPostService.m 的示例部分

  -(void)GetDeviceStatus:(NSString *)DeviceID RestID:(NSNumber *)ReID
{
    NSLog(@"GetDeviceStatus");
    NSDictionary * Parameters=[[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:DeviceID,ReID, @"GetStat", nil]
                                                             forKeys:[NSArray arrayWithObjects:@"DeviceUniqueId",@"ReID", @"OP",nil]];
    [service setReturnAction:@selector(GetDeviceStatusCallBack:)];
    [service setReturnDelegate:self];
    [service Send:@"GetStat" Mparams:Parameters Mdelegate:nil IsSycn:NO ExternalUrl:NO];

}
-(void)GetDeviceStatusCallBack:(id)value{
    NSLog(@"GetDeviceStatusCallBack");
    if([value isKindOfClass:[NSError class]]) {
        if ([ReturnDelegate respondsToSelector:FetchCompleted]) {
           ((void (*)(id, SEL, id, id))[ReturnDelegate methodForSelector:FetchCompleted])(ReturnDelegate, FetchCompleted, nil, value);
        }
        return;
    }
    if ([ReturnDelegate respondsToSelector:FetchCompleted]) {
        ((void (*)(id, SEL, id, id))[ReturnDelegate methodForSelector:FetchCompleted])(ReturnDelegate, FetchCompleted, value, nil);
    }
}

这些被代码的不同部分调用,这简化了代码,

    SE_MidPostService * service=[[SE_MidPostService alloc] init];
    [service setReturnDelegate:self];
    [service setFetchCompleted:@selector(DeviceStatusCheck:err:)];
    [service GetDeviceStatus:uuid RestID:id;
}

-(void)DeviceStatusCheck:(NSNumber *)Result err:(NSError *)err{
    if (err!=nil) {...}
//does what ever is needed
}

工具主要突出显示返回发生的代码。

((void (*)(id, SEL, id, id))[ReturnDelegate methodForSelector:FetchCompleted])(ReturnDelegate, FetchCompleted, value, nil);

我原以为 ARC 会解决这个问题,但事实并非如此。 我确实阅读了一些有关 autoreleasepool 的内容。我需要在成功编码中添加这个吗?

@autoreleasepool {
    // Code that creates autoreleased objects.
}

我希望我在这里有足够的信息。抱歉,我是 iOS 的新手,没有帮助。

最佳答案

所以如果其他人想要我的问题解决方案,我确实完全摆脱了子类。

这确实在编码方面增加了额外的工作,但不会有任何泄漏。

这是我使用的代码。我还观看了 wwdc 2013 内存管理 session 。帮助很大。

NSString * Murl;
        Murl = [NSString stringWithFormat:@"http://%@/service.aspx",[[GlobalData sharedGlobalData].settings ServerIP]];
        Murl=[Murl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:Murl]];
        __weak typeof(self) weakmyself = self;
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        manager.requestSerializer = [AFHTTPRequestSerializer serializer];
        [manager POST:Murl parameters:Parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSNumber *num = [NSNumber numberWithInteger: [string integerValue]];
            @autoreleasepool{
                //NSLog(@"success %@", string);
                [weakmyself Callbackfunction:num err:nil];
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            //NSLog(@"error %@", error);
            NSError * err = error;
            @autoreleasepool{
                [weakmyself Callbackfunction:nil err:err];

            }
        }];

关于ios - 启用 ARC 的 AFNetworking 2 后异步内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21546088/

相关文章:

ios - KVO 绑定(bind)快速失败

objective-c - UIInterfaceOrientation 对象的返回值是否等于 bool 变量?

ios - 无法获得 supportedInterfaceOrientationsForWindow 以使用 Swift 1.2

objective-c - 根据字符串的长度更新 NSTextField 的宽度

android - Leak Canary - 未显示 libgdx 应用程序的引用堆栈

iphone - 如果我与客户共享未签名的 XCARCHIVE 文件,他们可以看到源代码吗?

ios - iOS 中的 NSFaultingOrderedSet

ios - 来自 images.xcassets 的 Xcode 5 切片图像,在 xib 中正确拉伸(stretch),但在运行时不正确

c++ - 此代码是否会产生内存泄漏或是否干净?

Android - Activity 的局部变量与实例变量的性能