0
[client enqueueBatchOfHTTPRequestOperations:@[profileOperation,commFriendsOperation] progressBlock:^(NSUInteger finished, NSUInteger total){} completionBlock:^(NSArray *completedRequests){
//Code here
}]

以下のコードは、AFNetworking バッチ リクエストの成功ブロックにあります。計測器は、コメントされているように、コード ブローにメモリ リークがあることを示しています。しかし、どのように漏れたのか、どうすれば修正できるのかわかりません。

前もって感謝します。

AFHTTPRequestOperation *commFriendsRequest = [completedRequests objectAtIndex:1];
    if(!commFriendsRequest.error&&commFriendsRequest.responseData){
        //Leak 46.2%
        NSDictionary *commDic = [NSJSONSerialization JSONObjectWithData:commFriendsRequest.responseData options:NSJSONReadingMutableContainers error:NULL];
        int status1 = [[commDic objectForKey:@"status"]intValue];
        if(status1 == kSuccessCode){
            NSArray *commFriendsArray = [commDic objectForKey:@"data"];
            if(commFriendsArray&&commFriendsArray.count){
                //Leak 30.8%
                NSMutableArray *userItems = [NSMutableArray arrayWithCapacity:commFriendsArray.count];
                for(NSDictionary *dic in commFriendsArray){
                    //Leak 23.1%
                    userItem *item = [[userItem alloc]initFromServer:dic];
                    [userItems addObject:item];
                }
                if(profile){//Both Success
                    profile.commonFriends = userItems;
                    successBlock(profile);//block call back
                }else{
                    if(status0==kSuccessCode){
                        successBlock(userItems);//block call back
                    }else{
                        NSError *error = [NSError errorWithDomain:kErrorDomain code:status0 userInfo:nil];
                        failedBlock(error);//block call back
                    }
                }
            }else if(status0==kSuccessCode){//CommFriends 0 has profile
                successBlock(profile);//block call back
            }
        }else{
            if(status0==kSuccessCode){//CommFriends failed has profile
                successBlock(profile);//block call back
            }else{//Both failed
                NSError *error = [NSError errorWithDomain:kErrorDomain code:status1 userInfo:nil];
                failedBlock(error);//block call back
            }
        }
    }else{
        failedBlock(commFriendsRequest.error);
    }


//[[userItem alloc] initFromServer:dict] code
-(id)initFromServer:(NSDictionary *)dict{
if ((self = [super init])) {
    NSString *_userID = [dict objectForKey:@"userID"];
    NSString *_userName = [dict objectForKey:@"userName"];
    genderType _userGender = [[dict objectForKey:@"userGender"] integerValue];
    NSString *_userHeadImageURL = [dict objectForKey:@"userHeadImageURL"];
    NSString *_source = [dict objectForKey:@"source"];
    int _likeCount = [[dict objectForKey:@"likedCount"] intValue];
    int _sameFriends = [[dict objectForKey:@"sameFriends"] intValue];
    NSString *_homePage = [dict objectForKey:@"homePage"];

    NSString *_createTime = [dict objectForKey:@"createTime"];
    if([dict objectForKey:@"dis"])
        _distance = [[dict objectForKey:@"dis"]floatValue];
    else
        _distance = 0;

    if ([dict objectForKey:@"uid"]) {
        self.uid = [[dict objectForKey:@"uid"] intValue];
    }
    else{
        self.uid = -1;
    }

    self.userID = _userID;
    self.userName = _userName;
    self.userGender = _userGender;
    self.userHeadImageURL = _userHeadImageURL;
    self.source = _source;
    self.likeCount = _likeCount;
    self.sameFriends = _sameFriends;
    if (_homePage && ![_homePage isKindOfClass:[NSNull class]]) {
        self.homePage = _homePage;
    }

    if([dict objectForKey:@"hasJoin"]){
        self.hasJoined = [[dict objectForKey:@"hasJoin"]boolValue];
    }

    if (_createTime && ![_createTime isKindOfClass:[NSNull class]]) {
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
        self.createTime = [dateFormatter dateFromString:_createTime];
    }

    NSString *c = [dict objectForKey:@"comment"];
    if (c && ![c isKindOfClass:[NSNull class]]) {
        self.comment = c;
    }
}
return self;

}

4

2 に答える 2

0

Instruments は、リークしたオブジェクトが割り当てられた場所を示します (それがどのオブジェクトであるかを理解するのに役立つため) が、それはリークが割り当てまたはその近くにあることを意味するわけではありません。リークは、オブジェクトを過剰保持または不足解放する他のコードで発生する可能性があります。特定のリークされたオブジェクトの履歴を確認して (アドレスの横にある丸矢印ボタンをクリック)、リリースが保持によってバランスが取れていない場所を確認する必要があります。

おそらくバックグラウンド スレッドでこのコードを実行しており、自動解放プールを用意していません。ARC は、場合によってはオブジェクトを自動解放します。Apple フレームワークを呼び出している場合、それらは依然として非 ARC である可能性があるため、確実にオブジェクトを自動解放している可能性があります。そのため、引き続き自動解放プールが必要です。

Cocoa はメイン スレッドで自動解放プールを作成しますが、バックグラウンド スレッドでは何もしません。NSOperation などを使用せずにバックグラウンド スレッドで何かを開始する場合は、次のように @autoreleasepool でそのスレッドをラップする必要があります。

- (void)doSomething {
    [self performSelectorInBackground:@selector(backgroundSomething)];
}

- (void)backgroundSomething {
    @autoreleasepool {
        NSLog(@"Here I am in the background, doing something.");
        myArray = [[NSMutableArray alloc] init];
        // etc.
    }
}
于 2013-11-15T07:37:41.983 に答える