0

나는 현재 메모리 누수가있는 애니메이션 시계를 가지고 있습니다. 나는 현재 이미지 위에 물건을 놓을 수있는 것처럼 보이지만 멀리 가져 가거나 반드시 지워서는 안됩니다 (초침이 다른 두 위치에 있지 않도록 시계 전체를 다시 그려야하는 것은 제외).화면에 그려진 이미지를 제거하고 ARC가 회수 할 수 있도록 모든 링크를 해제하려면 어떻게해야합니까?

시계의 구성 요소를 삭제하기위한 코드는 다음과 같습니다

for(UIView *image in self.toWipe) 
{ 
    [image removeFromSuperview]; 
} 
[self.toWipe removeAllObjects]; 

초침을 그립니다 코드입니다 (시간과 분의 치료가 동일) :

CGAffineTransform secondTransform = CGAffineTransformMakeTranslation(centerX, centerY); 
secondTransform = CGAffineTransformTranslate(secondTransform, -10, -189); 
secondTransform = CGAffineTransformRotate(secondTransform, seconds/60.0 * M_PI * 2.0); 
UIImageView *secondHandView = [[UIImageView alloc] initWithImage:secondHandImage]; 
secondHandView.transform = secondTransform; 
[self.view addSubview:secondHandView]; 
[self.toWipe addObject:secondHandView]; 
[self.toWipe addObject:secondHandImage]; 

난을 가면 한 각 반복마다 시계면을 그려서 지우지 않는 그려진 초침; 그렇게하지 않으면 초침 (또는 다른 사람)이 360 ° 번 채워진 디스크에 도달 할 때까지 파이 조각을 날려 버릴 것입니다. 기억은 천천히 그러나 꾸준히 자랍니다. 그리고 두 번째 손은 움직임이 더 잘게됩니다.

사용 된 물건을 위탁하기 위해 내가 할 수 있거나해야 할 일이 있습니까? 이 프로젝트에서 ARC를 사용하고 있습니다. 나는 더 많이 또는 다르게 내가 줄 수있는 것을 알고 싶습니다. 그래서 메모리 누수가 수정되었습니다. cruft에 함께

감사

--EDIT--

다음은, 주석 및 주석 cruft에이없는, 방법 체이다. 그것은 예외를 해결하지 않고, 예외는 몸에 아무것도에서 발생하지 않습니다 :

int height = floor([[UIScreen mainScreen] bounds].size.height + .4); 
int width = floor([[UIScreen mainScreen] bounds].size.width + .4); 
UIImage *backgroundImage = nil; 

if (height == 2048 || height == 2008 || height == 1024 || height == 1004 || height == 984) 
{ 
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-Portrait.png"]; 
    } 
    else 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-Landscape.png"]; 
    } 
} 
else if (height == 1536 || height == 768 || height == 748 || height == 728) 
{ 
    backgroundImage = [UIImage imageNamed:@"Background-Default-Landscape.png"]; 
} 
else if (height == 1136 || height == 1116 || height == 1096) 
{ 
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-568.png"]; 
    } 
    else 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-Rotated-568.png"]; 
    } 
} 
else if (height == 960 || height == 940 || height == 920 || height == 480 || height == 460 || height == 440) 
{ 
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default.png"]; 
    } 
    else 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-Rotated.png"]; 
    } 
} 
else if ((height == 640 || height == 620 || height == 600) && (width == 1136 || width == 1116 || width == 1096)) 
{ 
    backgroundImage = [UIImage imageNamed:@"Background-Rotated-568.png"]; 
} 
else if ((height == 640 || height == 620 || height == 600 || height == 320 || height == 300 || height == 280) && (width == 960 || width == 940 || width == 920 || width == 480 || width == 470 || width == 410)) 
{ 
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-Portrait.png"]; 
    } 
    else 
    { 
     backgroundImage = [UIImage imageNamed:@"Background-Default-Rotated.png"]; 
    } 
} 
else 
{ 
    backgroundImage = [UIImage imageNamed:@"Background-Default-Portrait.png"]; 

} 
backgroundImage = [UIImage imageNamed:@"Background-Default-Landscape.png"]; 


if (!UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) 
{ 
    int juggle = height; 
    height = width; 
    width = juggle; 
} 
NSUInteger centerX = width * .5; 
NSUInteger centerY = height * .5; 

CGRect containerRect = CGRectZero; 
containerRect.size = [[UIScreen mainScreen] bounds].size; 

for(UIView *image in self.toWipe) 
{ 
    [image removeFromSuperview]; 
} 
[self.toWipe removeAllObjects]; 
self.view.backgroundColor = [UIColor colorWithPatternImage:backgroundImage]; 
//  UIView *background = [UIImage imageNamed:@"Background-Default-Landscape.png"]; 
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage]; 
[self.view addSubview:backgroundView]; 
[self.toWipe addObject:backgroundView]; 
self.containerView = [[UIView alloc] initWithFrame:containerRect]; 
// float hours = 5.0; 
// float minutes = 19.0; 
// float seconds = 312.0; 
// int timeStampMilliseconds = (ceil([[NSDate date] timeIntervalSince1970] * 1000.0)); 
// double timeStampMilliseconds = [[NSDate date] timeIntervalSince1970] * 1000.0; 
double timeStampMilliseconds = CACurrentMediaTime() * 1000; 
double hours = fmodf(timeStampMilliseconds, 86400000)/3600000.0; 
double minutes = fmodf(timeStampMilliseconds, 3600000)/60000.0; 
double seconds = fmodf(timeStampMilliseconds, 60000)/1000.0; 
// NSLog(@"Milliseconds: %lf, Hours: %lf, minutes: %lf, seconds: %lf", timeStampMilliseconds, hours, minutes, seconds); 
[self.containerView removeFromSuperview]; 
self.containerView = [[UIView alloc] initWithFrame:containerRect]; 
UIImage *hourHandImage = [UIImage imageNamed:@"hour-hand.png"]; 
UIImageView *hourHandView = [[UIImageView alloc] initWithImage:hourHandImage]; 
hourHandImage = [UIImage imageNamed:@"hour-hand.png"]; 
hourHandView = [[UIImageView alloc] initWithImage:hourHandImage]; 
[self.view addSubview:hourHandView]; 

// UIImage *dotImage = [UIImage imageNamed:@"dot.png"]; 
// UIImageView *dotView = [[UIImageView alloc] initWithImage:dotImage]; 
// dotView.transform = CGAffineTransformMakeTranslation(centerX, centerY); 
// [self.view addSubview:dotView]; 



hourHandView.layer.anchorPoint = CGPointMake(0.5f, 0.5f); 
CGAffineTransform hourTransform = CGAffineTransformMakeTranslation(centerX, centerY); 
    hourTransform = CGAffineTransformTranslate(hourTransform, -22, -122); 
    hourTransform = CGAffineTransformRotate(hourTransform, hours/12.0 * M_PI * 2.0); 
    CGAffineTransform minuteTransform = CGAffineTransformMakeTranslation(centerX, centerY); 
    minuteTransform = CGAffineTransformTranslate(minuteTransform, -10, -182); 
    minuteTransform = CGAffineTransformRotate(minuteTransform, minutes/60.0 * M_PI * 2.0); 
    // hourTransform = CGAffineTransformTranslate(hourTransform, -sin(angle) * 50 + 122 , -cos(angle) * 50 + 122); 


// hourTransform = CGAffineTransformTranslate(hourTransform, -330, 330); 
hourHandView.transform = hourTransform; 
[self.toWipe addObject:hourHandImage]; 
[self.toWipe addObject:hourHandView]; 
UIImage *minuteHandImage = [UIImage imageNamed:@"minute-hand.png"]; 
UIImageView *minuteHandView = [[UIImageView alloc] initWithImage:minuteHandImage]; 
minuteHandView.transform = minuteTransform; 
[self.view addSubview:minuteHandView]; 
[self.toWipe addObject:minuteHandView]; 
[self.toWipe addObject:minuteHandImage]; 

minuteTransform = CGAffineTransformRotate(minuteTransform, minutes/60.0 * M_PI * 2.0); 
UIImage *secondHandImage = [UIImage imageNamed:@"second-hand.png"]; 
CGAffineTransform secondTransform = CGAffineTransformMakeTranslation(centerX, centerY); 
secondTransform = CGAffineTransformTranslate(secondTransform, -10, -189); 
secondTransform = CGAffineTransformRotate(secondTransform, seconds/60.0 * M_PI * 2.0); 
UIImageView *secondHandView = [[UIImageView alloc] initWithImage:secondHandImage]; 
secondHandView.transform = secondTransform; 
[self.view addSubview:secondHandView]; 
[self.toWipe addObject:secondHandView]; 
[self.toWipe addObject:secondHandImage]; 



// hourHandView.layer.anchorPoint = CGPointMake(centerX, centerY); 
// hourHandView.layer.affineTransform = CGAffineTransformRotate(transform, hour/(12.0 * M_PI * 2.0)); 
// UIImageView *minuteHandView = [[UIImageView alloc] initWithImage:minuteHandImage]; 
// UIImageView *secondHandView = [[UIImageView alloc] initWithImage:secondHandImage]; 

// [self.view addSubview:minuteHandView]; 
// [self.view addSubview:secondHandView]; 
+0

: 여기

내가 작업 한 시계 앱 사용한 코드를 무엇입니까? – JonahGabriel

+2

이것은 실제 코드 일 수 없습니다. 당신은'UIImage'를'toWipe'에 넣은 다음 응답하지 않는'removeFromSuperview'를 보냅니다. 그것은 예외를 일으킬 것입니다. –

+0

3 개의 이미지를 toWipe에 넣고 모두에서 removeFromSuperview를 호출합니다. 내 게시물을 편집하여 메시지 본문을 포함시킵니다. – JonathanHayward

답변

2

것은 그냥 제거하고 반복해서 이미지 뷰를 추가하는 대신 각 초 변환을 적용 봤어? 당신이 secondHandImage을 받고 어떻게 표시 할 수 있습니다, 그냥 호기심

-(void)updateClock 
{ 
    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:inDate]; 
    NSInteger seconds = [dateComponents second]; 
    NSInteger minutes = [dateComponents minute]; 
    NSInteger hours = [dateComponents hour]; 
    //NSLog(@"raw: hours:%d min:%d secs:%d", hours, minutes, seconds); 
    if (hours > 12) hours -=12; //PM 

    //set angles for each of the hands 
    CGFloat secAngle = Degrees2Radians(seconds/60.0*360); 
    CGFloat minAngle = Degrees2Radians(minutes/60.0*360); 

    CGFloat minAdjustment = minAngle/12.0; 
    CGFloat hourAngle = Degrees2Radians(hours/12.0*360) + minAdjustment; 

    //reflect the rotations + 180 degres since CALayers coordinate system is inverted 
    secHand.transform = CATransform3DMakeRotation (secAngle+M_PI, 0, 0, 1); 
    minHand.transform = CATransform3DMakeRotation (minAngle+M_PI, 0, 0, 1); 
    hourHand.transform = CATransform3DMakeRotation (hourAngle+M_PI, 0, 0, 1); 
} 
+0

나는 그것에 대해 생각해 보았다. 부동 소수점 체인의 부정확성없이 그렇게 할 수있는 방법이 있습니까? IE는 "이 이미지를 정확하게 0으로 리셋 한 다음 새 이미지가 생성 된 것과 같은 양만큼 회전 시키십시오"라고 말할 수있는 방법이 있습니다. – JonathanHayward

+0

추가 된 질문 : "앞으로 감기, 뒤로 돌리기"를 n 번 수행하면 자릿수 O (n) 또는 O (log n)가 손상됩니까? O (log n) 근처이거나 작은 경우,이 접근법을 너무 빨리 거부 할 수 있습니다. – JonathanHayward

+0

초기 설정 및보기의 점진적 변경을 위해 코드를 리팩터링했습니다. 코드는 http://stackoverflow.com/questions/19348298/how-to-deal-with-leaks-in-ios-when-memory-consumption-climbs-but-leaks-does-not-에 있습니다. 특히 메모리에있는 것이 아니라 초기 뷰를 렌더링 한 다음 나중에 업데이트하지 않는 이유는 무엇입니까? – JonathanHayward