2015-02-04 2 views
0

다른 개체의 특정 이미지를 확인하는 UIImageView의 하위 클래스 인 개체가 있습니다. 이미지가 있으면 ImageView에 표시되고, 그렇지 않으면 새 이미지를 다운로드하는 동안 임시 이미지가 표시됩니다. 다운로드가 완료되면 ImageView에 새 이미지가 표시됩니다. 이 객체를 "Imager"라고 부릅니다.Custom ImageView의 메모리 오버플로

이미 저를 테이블 뷰의 셀에 인스턴스화합니다. 어떤 이유로 Imager가 내 앱의 메모리를 넘치고 있습니다. Imager를 구현하기 전에, 앱의 메모리 사용량은 약 60Mb 였지만, 구현 후 300Mb로 바뀌 었습니다. 따라서 메모리 경고 메시지가 표시되고 예상대로 아이폰이 닫힙니다.

알고 싶습니다. 무엇이 잘못 되었나요? 그것은 복잡한 코드 또는 논리가 아니지만, 확실히 나는 메모리를 높이는 것을하고 있습니다. 나는 테이블 뷰를 추측 하겠지만 확실하지는 않습니다. Heres는

이미 저를위한 코드 : Imager.h

#import <UIKit/UIKit.h> 
#import "friend.h" 
#import "Group.h" 
#import "Mimo.h" 
@interface Imager : UIImageView 
-(void)loadFriendImage:(friend*)theFriend; 
-(void)loadGroupImage:(Group*)group; 
@end 

Imager.m 이는 이미 저이게

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     static NSString *CellIdentifier = @"friendCell"; 
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

     if(cell == nil) 
      cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 

    Imager *accessory; 
    friend *workingFriend = [thisUser.friendsList objectAtIndex:indexPath.row]; 
    cell.textLabel.text = workingFriend.username; 
    //----------------Setup Accessory View----------------------------------- 

        accessory = [[Imager alloc]init]; 
        [accessory loadFriendImage:[thisUser.friendsList objectAtIndex:indexPath.row]]; 
        accessory.frame = CGRectMake(cell.accessoryView.frame.origin.x, cell.accessoryView.frame.origin.y, 72.0, 72.0); 
        accessory.contentMode = UIViewContentModeScaleAspectFill; 
        accessory.clipsToBounds = YES; 



        cell.accessoryView = accessory; 

        cell.textLabel.textColor = [UIColor blackColor]; 
        [cell.textLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:17]]; 
        //---------------------------------------------------------- 
    return cell; 
} 

개체 사용 표이다

#import "Imager.h" 
#import "Group.h" 
@implementation Imager 

-(void)loadFriendImage:(friend*)theFriend{ 
    if(!theFriend.flagDownloaded){ 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       if(theFriend.userImg == nil) 
        [self setImage:[UIImage imageNamed:@"[email protected]"]]; 
       else{ 
        [self setImage:theFriend.userImg]; 
       } 
      }); 
      NSLog(@"[IMAGER]: Will load %@ image.",theFriend.username); 
     UIImage *friendImage = [theFriend downloadImageBlocked]; 
     if(friendImage != nil){ 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       [self setImage:friendImage]; 
      }); 
     } 


     }); 
    } 
    else 
    { 
     NSLog(@"[IMAGER]: %@ image already exists",theFriend.username); 
     if(self.image == nil) 
      [self setImage:theFriend.userImg]; 
    } 

} 
-(void)loadGroupImage:(Group*)group 
{ 
    if(!group.flagDownloaded){ 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       [self setImage:[UIImage imageNamed:@"[email protected]"]]; 
      }); 
      NSLog(@"[IMAGER]: Will load %@ image.",group.groupName); 
      UIImage *groupImage = [group downloadImageBlocked]; 
      if(groupImage != nil){ 
       dispatch_sync(dispatch_get_main_queue(), ^{ 
        [self setImage:groupImage]; 
       }); 
      } 


     }); 
    } 
    else 
    { 
     [self setImage:group.groupImage]; 
    } 
} 

이미지를 다운로드하는 이미지 차단 기능 다운로드

-(UIImage*)downloadImageBlocked 
{ 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://tatohouston.azurewebsites.net/getUserImg.php"]]; 
    [request setHTTPMethod:@"POST"]; 
    [request addValue:@"postValues" forHTTPHeaderField:@"METHOD"]; 
    NSDictionary *tempDic; 

    //--------------------------------- 
    tempDic = @{@"userid":userID}; 
    //serialize the dictionary data as json 
    NSData *dataPost = [[tempDic copy] JSONValue]; 
    [request setHTTPBody:dataPost]; //set the data as the post body 

    [request addValue:[NSString stringWithFormat:@"%lu",(unsigned long)dataPost.length] forHTTPHeaderField:@"Content-Length"]; 

    NSData *tmpData = [[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil] base64EncodedDataWithOptions:NSUTF8StringEncoding]; 
    if(tmpData != nil){ 
     returnData = [[NSData alloc]initWithBase64EncodedData:tmpData options:NSUTF8StringEncoding]; 
    } 
    UIImage *friendImage; 

    if(returnData != nil){ 
     friendImage = [UIImage imageWithData:returnData]; 
     userImg = friendImage; 
     flagDownloaded = YES; 
    } 
    return friendImage; 
} 
+0

유지되었지만 누출 된 메모리로 인한 누출 및 메모리 손실을 확인하려면 계측기를 사용하십시오. 후자는 여전히 가리키는 사용되지 않는 메모리입니다. Instruments의 Allocations 도구에서 Mark Generation (Heapshot)을 사용하십시오. 메모리 삐걱 거림을 찾기 위해 힙샷을 사용하는 방법은 다음을 참조하십시오. [bbum 블로그] (http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak- using- heapshot-analysis-to-find-desirable-memory-growth /) – zaph

+0

약간의 제안 : 변수를 만들 때 friendInage를 nil로 설정해야합니다. 그렇지 않으면 returnData가 발생하면 다른 임의의 포인터를 반환 할 때 버그가 발생할 수 있습니다 무. – ozz

답변

0

요청으로부터 얼마나 많은 NSData가 반환됩니까? 나는 그것이 일반적으로 인코딩되지 않은 것보다 1.37 배 더 큰 Base64 인코딩 된 데이터를 사용하고 있음을 알고있다. 내 생각 엔 귀하의 이미지 데이터가 상당히 큰 것입니다.

+0

요청의 NSData는 약 121894 바이트입니다. 그렇겠습니까? 보통이 데이터를로드하는 행이 10 개 미만입니다. –

+0

메모리 할당을 위해 앱을 프로파일하고 그 메모리를 모두 차지하는 것으로 보이는 것을 정확하게 결정하고 위에 제시된 @Zaph로 다시보고하십시오. 그것은 올바른 방향으로 당신을 도울 것입니다. – ozz

관련 문제