Где утечка памяти в моем приложении для iPhone? - PullRequest
0 голосов
/ 09 ноября 2010

Это простое приложение, которое берет 30 изображений из моей папки ресурсов, помещает их в NSMutableArray во время viewDidLoad, а затем изменяет изображение на основе данных акселерометра. У меня есть UIImageView от IB, охватывающий весь вид, и когда акселерометр обновляет свою информацию, он меняет uiimageview.image на разное изображение. Работает около 10 секунд, а затем вылетает с:

Program received signal:  “0”.
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")

После осмотра здесь звучит как утечка памяти. Вот код, который я использую:

Interface:
{
    UIAccelerometer *accel;
    IBOutlet UIImageView *pic;
    NSMutableArray *picArr;
}

Implementation:

- (void)viewDidLoad
{   
[super viewDidLoad];

picArr = [[NSMutableArray alloc] init];  //array of pics to be used
NSString *path = [[NSString alloc] init]; //dynamic path of images to save to array

for (int i = 1; i <= 30; i++)
{
    path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"];

    [picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]];

}

accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 0.5f;

[path release];

pic.image = [picArr objectAtIndex:15];
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{

if(acceleration.y < 0.0f) //goes thru the tilted left pics
{
    for (int i = 0; i <= 15; i++)
    {                       
        if( acceleration.y >= (-(15.0f-(double)i)/30.0f) && acceleration.y <  (-(14.0f-(double)i)/30.0f) )
        {
            pic.image = [picArr objectAtIndex:i+1];
        }
    }
}

else if(acceleration.y > 0.0f) //goes thru tilted right pics
{       
    for (int i = 1; i <= 14; i++)
        if( acceleration.y > ((double)i/30.0f) && acceleration.y <= ((double)(i+1)/30.0f) )
        {
            pic.image = [picArr objectAtIndex:i+15];
        }
}
}

Пожалуйста, дайте мне знать, если я пропустил любую соответствующую информацию.

Ответы [ 2 ]

1 голос
/ 09 ноября 2010

Это не сбой, вызванный утечкой памяти, а чрезмерным выпуском памяти. Ваш сбой вызван этой строкой:

[path release];

Удалите эту строку, и все будет в порядке. Во всяком случае, для некоторых значений штрафа; большинство из того, что говорит Джордж, также применимо.

Причина в том, что освобождаемый путь будет таким:

path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"];

Это объект с эффективным счетом удержания, равным нулю. Несмотря на то, что он имеет положительный счет сохранения, он уже был автоматически выпущен и будет освобожден, когда вы вернетесь в основной цикл событий.

Вы также должны удалить эту строку:

NSString *path = [[NSString alloc] init]; //dynamic path of images to save to array

Причина в том, что вы присваиваете pathForResource результат, а не используете его на самом деле. Конечно, вам нужно будет объявить path как переменную. Я предлагаю изменить строку pathForResource следующим образом:

NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"nativity_test_%i", i] ofType:@"jpg"];

Это разумное изменение, поскольку нет причин, по которым вам это нужно вне цикла.

Вы также должны исправить эту строку:

[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]];

[UIImage alloc] возвращает UIImage с эффективным счетом сохранения 1. Добавление его в массив увеличит его до двух. Если вы просто освободите массив позже, это приведет к утечке памяти. Вместо этого:

[picArr addObject:[[[UIImage alloc] initWithContentsOfFile:path]] autorelease];

Это будет означать, что вы добавляете в массив UIImage с эффективным счетом сохранения 0, что увеличивает его до 1, делая массив единственным владельцем объекта. Позже, когда массив исчезнет, ​​то же самое произойдет с большинством изображений. (ImageView также будет принадлежать тому, что ему назначено.)

Не расстраивайтесь из-за этого: однажды скоро вы просто внезапно получите его и удивитесь, почему это когда-либо вызывало у вас головную боль. :)

0 голосов
/ 09 ноября 2010

Здесь есть пара проблем:

1) Вы не освобождаете объекты UIImage, которые добавляете в "picArr".

Эта строка:

[picArr addObject:[[UIImage alloc] initWithContentsOfFile:path]];

Вместо этого должно быть что-то вроде этого:

UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
[picArr addObject: image];
[image release];

Полагаю, вы могли бы также сделать:не нужно делать NSString * path = [[NSString alloc] init];Вы можете просто сделать: NSString * path;Вы присваиваете переменной пути значение в этом первом цикле, поэтому нет необходимости выделять + init.После того, как вы измените это, вы можете избавиться от этой строки:

[path release];

3) Я не вижу, куда вы выпускаете сам «picArr», вам понадобится.Возможно, вы уже делаете это, но не включили этот фрагмент кода в свой пост.

...