iOS ARC 앱 (요청시 더 많은 코드 제공)을 준비 중이며 이전에는 다수의 이미지를 제작하고 폐기했습니다. 나는 removeFromSuperview를 호출하고 더 이상 사용되지 않는 이미지에 대한 모든 참조를 제거하려고 했더라도 어딘가에 여전히 이미지에 대한 참조가 있다고 생각했습니다. 나는 Leaks를 시도했고 Leaks는 대략 17M을 시작으로 시간이 지남에 따라 메모리 사용량이 대략 선형 적으로 증가했다고보고했습니다.메모리 소비가 올라 갔지만 누수가 누출을 감지하지 못하면 iOS에서 누수를 처리하는 방법은 무엇입니까?
이미지에 대한 모든 참조가 인스턴스 변수로 바뀌었기 때문에 한정된 크기의 고정 된 메모리를 사용하고 시계 바늘에 사용되는 이미지를 제거하는 대신 변형되었습니다. 불행히도 시간이 지남에 따라 메모리 사용이 서서히 증가하는 결과를 낳았습니다. 17M이 아닌 5M에서 시작했지만, 그렇지 않은 경우 동일한 문제가 더 나은 출발점으로 전환되었습니다.
내 코드의 트림 된 버전은 다음과 같습니다. 이것에 관한 누설 (또는 "누수가 누설을 나타내지 않았으므로"의사 누설 ")이 무엇인지, 그리고 어떻게 시작될 때 코드가 사용하는 메모리 경계에 가까이 머무를 수 있는지 말해 줄 수 있습니까? I는 두 가지 방법으로, 초기 표시를위한 하나의 증분 업데이트 하나에 하나의 방법 리팩토링 한
- (void) renderScreen
{
int height = floor([[UIScreen mainScreen] bounds].size.height + .4);
int width = floor([[UIScreen mainScreen] bounds].size.width + .4);
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"];
}
if (!UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation))
{
int juggle = height;
height = width;
width = juggle;
}
NSUInteger centerX = width * .5;
NSUInteger centerY = height * .5;
_containerRect = CGRectZero;
_containerRect.size = [[UIScreen mainScreen] bounds].size;
self.view.backgroundColor = [UIColor colorWithPatternImage:_backgroundImage];
_backgroundView = [[UIImageView alloc] initWithImage:_backgroundImage];
[self.view addSubview:_backgroundView];
if (_changed)
{
_containerView = [[UIView alloc] initWithFrame:_containerRect];
}
double timeStampSeconds = [[NSDate date] timeIntervalSince1970];
double hours = fmod(timeStampSeconds/86400, 24);
double minutes = fmod(timeStampSeconds/3600, 60);
double seconds = fmod(timeStampSeconds, 60);
NSLog(@"Milliseconds: %lf, Hours: %.0f, minutes: %.0f, seconds: %.0f", timeStampSeconds * 1000.0, hours, minutes, seconds);
[_containerView removeFromSuperview];
_containerView = [[UIView alloc] initWithFrame:_containerRect];
_hourHandImage = [UIImage imageNamed:@"hour-hand.png"];
_hourHandView = [[UIImageView alloc] initWithImage:_hourHandImage];
_hourHandImage = [UIImage imageNamed:@"hour-hand.png"];
_hourHandView = [[UIImageView alloc] initWithImage:_hourHandImage];
[self.view addSubview:_hourHandView];
_hourHandView.layer.anchorPoint = CGPointMake(0.5f, 0.5f);
_hourTransform = CGAffineTransformMakeTranslation(centerX, centerY);
_hourTransform = CGAffineTransformTranslate(_hourTransform, -17, -127);
_hourTransform = CGAffineTransformRotate(_hourTransform, hours/12.0 * M_PI * 2.0);
_minuteTransform = CGAffineTransformMakeTranslation(centerX, centerY);
_minuteTransform = CGAffineTransformTranslate(_minuteTransform, -10, -182);
_minuteTransform = CGAffineTransformRotate(_minuteTransform, minutes/60.0 * M_PI * 2.0);
_hourHandView.transform = _hourTransform;
_minuteHandImage = [UIImage imageNamed:@"minute-hand.png"];
_minuteHandView = [[UIImageView alloc] initWithImage:_minuteHandImage];
_minuteHandView.transform = _minuteTransform;
[self.view addSubview:_minuteHandView];
_minuteTransform = CGAffineTransformRotate(_minuteTransform, minutes/60.0 * M_PI * 2.0);
_secondHandImage = [UIImage imageNamed:@"second-hand.png"];
_secondTransform = CGAffineTransformMakeTranslation(centerX, centerY);
_secondTransform = CGAffineTransformTranslate(_secondTransform, -10, -189);
_secondTransform = CGAffineTransformRotate(_secondTransform, seconds/60.0 * M_PI * 2.0);
_secondHandView = [[UIImageView alloc] initWithImage:_secondHandImage];
_secondHandView.transform = _secondTransform;
[self.view addSubview:_secondHandView];
}
--EDIT--
감사합니다. 증분 업데이트 메서드는 시계가 고정되어 서명 로깅 문이 정확히 한 번 호출되므로 한 번만 호출됩니다.
는 지금 업데이트 부분에 대해 가지고 :
- (void)render
{
[self renderScreenInitial];
[NSTimer scheduledTimerWithTimeInterval:0.002
target:self
selector:@selector(renderingTimer:)
userInfo:nil
repeats:YES];
}
- (void) renderScreenIncremental
{
int height = floor([[UIScreen mainScreen] bounds].size.height + .4);
int width = floor([[UIScreen mainScreen] bounds].size.width + .4);
if (!UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation))
{
int juggle = height;
height = width;
width = juggle;
}
double decibelAngle = M_PI/4 + (_decibel/60) * M_PI/2;
double decibelAngleDifference = decibelAngle - _previousDecibelAngle;
_previousDecibelAngle = decibelAngle;
NSLog(@"%lf %lf", _decibel, decibelAngle);
_decibelNeedleView = [[UIImageView alloc] initWithImage:_decibelNeedle];
// CGAffineTransform decibelTransform = CGAffineTransformMakeTranslation(centerX, centerY);
CGAffineTransform decibelTransform = CGAffineTransformMakeRotation(decibelAngleDifference);
decibelTransform = CGAffineTransformTranslate(decibelTransform, sin(decibelAngle - .06) * -298, -cos(decibelAngle - .06) * 298);
_decibelNeedleView.transform = decibelTransform;
[self.view addSubview:_decibelNeedleView];
double timestampSeconds = [[NSDate date] timeIntervalSince1970];
double timestampSecondsDifference = timestampSeconds - _previousTimestampSeconds;
_previousTimestampSeconds = timestampSeconds;
double hoursDifference = fmod(timestampSecondsDifference/86400, 24);
double minutesDifference = fmod(timestampSecondsDifference/3600, 60);
double secondsDifference = fmod(timestampSecondsDifference, 60);
NSLog(@"Milliseconds: %lf, Hours: %.0f, minutes: %.0f, seconds: %.0f", timestampSecondsDifference * 1000.0, hoursDifference, minutesDifference, secondsDifference);
_hourHandView.transform = CGAffineTransformMakeRotation(hoursDifference);
_minuteHandView.transform = CGAffineTransformMakeRotation(minutesDifference);
_secondHandView.transform = CGAffineTransformMakeRotation(secondsDifference);
}
-(void)renderingTimer:(NSTimer *)timer {
[self renderScreenIncremental];
}
내가 도움을 주셔서 감사합니다. 디스플레이를 한 번 업데이트 한 다음 계속 업데이트하지 않는 이유를 알고 있습니까?
감사합니다.
'renderingTimer :'의 호출 여부를 확인할 수 있습니까? 그리고 메인 큐에서'render'를 호출했다고 가정합니다. BTW, 0.002 초마다 호출 할 필요는 없습니다. 그 타이머를 합리적인 수준으로 줄일 것입니다 (초당 30-60 번). – Rob