массив сохранить вопрос - PullRequest
0 голосов
/ 08 июня 2010

Я довольно новичок в Objective-C, большинство из них ясно, однако, когда дело доходит до управления памятью, я немного не хватает. В настоящее время мое приложение работает во время NSURLConnection, когда вызывается метод -(void)connectionDidFinishLoading:(NSURLConnection *)connection, когда я ввожу метод для анализа некоторых данных, помещаю их в массив и возвращаю этот массив. Однако я не уверен, что это лучший способ сделать это, поскольку я не освобождаю массив из памяти в пользовательском методе (method1, см. Прилагаемый код)

Ниже приведен небольшой скрипт, чтобы лучше показать, что я делаю

.h файл

#import <UIKit/UIKit.h>

@interface memoryRetainTestViewController : UIViewController {

    NSArray *mainArray;

}

@property (nonatomic, retain) NSArray *mainArray;

@end

.m файл

#import "memoryRetainTestViewController.h"

@implementation memoryRetainTestViewController
@synthesize mainArray;


// this would be the parsing method
-(NSArray*)method1
{
    // ???: by not release this, is that bad. Or does it get released with mainArray
    NSArray *newArray = [[NSArray alloc] init];
    newArray = [NSArray arrayWithObjects:@"apple",@"orange", @"grapes", "peach", nil];

    return newArray;
}


// this method is actually
// -(void)connectionDidFinishLoading:(NSURLConnection *)connection
-(void)method2
{
    mainArray = [self method1];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    mainArray = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc {
    [mainArray release];
    [super dealloc];
}


@end

Ответы [ 2 ]

2 голосов
/ 08 июня 2010

Ваш -method1 сначала создает новый массив, а затем перезаписывает его новым:

NSArray *newArray = [[NSArray alloc] init]; // first array, retained
newArray = [NSArray arrayWithObjects:...];  // second array, auto-released, 
                                            // pointer to first one lost

Первый массив здесь просто просочился. Вы также пропускаете массив, сохраненный в ivar, просто используйте синтезированный установщик, чтобы избежать этого - он сохраняет и освобождает вас.

Если вы еще этого не сделали, прочитайте Руководство по управлению памятью для какао.

Лучшая версия:

- (NSArray *)method1 {
    NSArray *newArray = [NSArray arrayWithObjects:...];    
    return newArray;
}

- (void)method2 {
    self.mainArray = [self method1];
}
2 голосов
/ 08 июня 2010

Да, ваш newArray выпущен, когда mainArray выпущен. Но это только если method2 вызывается один раз.

Мы говорим о ссылках, так что если у вас есть

newArray = something
mainArray = newArray
[mainArray release]

обе переменные будут ссылаться только на NSArray*. Тогда в вашем случае newArray просто локально, поэтому проблем нет.

Проблема возникает, если вы звоните method2 дважды:

newArray = something
mainArray = newArray
newArray = something2
mainArray = newArray <- old reference is lost
[mainArray release] <- just something2 is released

Чтобы избежать этой проблемы, вы должны обязательно разблокировать mainArray перед перезаписью ссылки другим объектом.

РЕДАКТИРОВАТЬ: не заметил, что вы создавали массив дважды :) Нет, это не хорошо ..

...