NSMutableArray不保留值

时间:2011-08-06 01:14:11

标签: objective-c nsmutablearray

我创建了一个名为DataClass的类,我有这个方法

+(NSMutableArray*) returnList :(NSString *) sql
{

    NSMutableArray *tmpList=[[[NSMutableArray alloc]init]autorelease];

    sqlite3 *db;

    NSString *dbPath =[[NSBundle mainBundle] pathForResource:@"DB_MyReef" ofType:@"sqlite"];


    if (sqlite3_open([dbPath UTF8String],&db) ==SQLITE_OK)
    {

        sqlite3_stmt *ss;

        int rv = sqlite3_prepare_v2(db, [sql UTF8String], -1,&ss,NULL);

        if (rv==SQLITE_OK)
        {

            while (sqlite3_step(ss)==SQLITE_ROW) 
            {

                NSString *txt =[NSString stringWithUTF8String:(char *)sqlite3_column_text(ss,0)]; 
                [tmpList addObject:txt];
                [txt release];

            }
        }

        sqlite3_finalize(ss);
    }

    sqlite3_close(db);


    return tmpList; 


}

在我创建的另一个名为UserSelect的类中。

在h文件中

@interface UserSelect : UIViewController <UIPickerViewDelegate,UIPickerViewDataSource> {

    NSMutableArray *List;
    UIPickerView *myPicker; 

}

@property (nonatomic,retain) NSMutableArray *List;
@property (nonatomic,retain) UIPickerView *myPicker;


@end

和m文件

- (void)viewDidLoad {



    [super viewDidLoad];

    //List=[[NSMutableArray alloc] init;

    NSString *sql;
        //Loading Data
        if ([self.title isEqualToString:@"Marca Teste"]) 
        {
            sql=@"SELECT TESTMARK FROM TBL_TESTSMARK ORDER BY TESTMARK";
        }
        else
        {
            sql=@"SELECT PT_PARAMNAME FROM TBL_PARAMETERS "
            "WHERE COD IN "
            "(SELECT A.CODTEST FROM TBL_TEST AS A  "
            "INNER JOIN  "
            "TBL_TESTSMARK AS B "
            "ON  "
            "A.CODTESTMARK =B.COD "
            "WHERE " 
            "B.TESTMARK='Salifert')";
        }

    self.List=[[NSMutableArray alloc] init];
    self.List=[[NSMutableArray arrayWithArray:[DataClass returnList:sql]]retain];

    myPicker=[[UIPickerView alloc] init];
    myPicker.delegate=self;
    myPicker.dataSource=self;

        /*for (NSString *ts in List) {
            NSLog(@"%@",ts);
        }*/

        [self.view addSubview:myPicker];    


    }

好的,我打电话给这个方法,这个回归是预期的。

但是在UiPickerView方法中,我的List变量只保留NSMutable数组中的第一个对象。

这些是UIPicker方法

#pragma mark pickerView

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    NSLog(@"%@",@"numberOfComponentsInPickerView");
    return 1;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    NSLog(@"%@",@"numberOfRowsInComponent");

    return [List count];
}


-(NSString *)pickerView:(UIPickerView *) pickerView titleForRow:(NSInteger) row forComponent:(NSInteger) component
{
    NSString *txt=[[NSString alloc] initWithFormat:@"%@",[self.List objectAtIndex:(int)row]];
    return txt;
    [txt release];
}

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSString *txt=[[NSString alloc] initWithFormat:@"%@",[self.List objectAtIndex:(int)row]];

    [DataClass writePlist:txt toKey:TEST_MARK]; 

    [txt release];


}

我试图以多种方式启动List,出了什么问题?

1 个答案:

答案 0 :(得分:1)

看看这里:

NSString *txt =[NSString stringWithUTF8String:(char *)sqlite3_column_text(ss,0)]; 
[tmpList addObject:txt];
[txt release];

字符串txt是自动释放的(NSString stringXXX函数返回自动释放的字符串)。然后将其添加到tmpList并明确释放它。一旦自动释放池耗尽,该字符串将被释放。换句话说,你过度释放字符串。删除

[txt release];

并且值应由tmpList保留。由于tmpList也是自动释放的,因此不确定这是否重要。它可能会给你一个运行时错误。

这也是可疑的:

self.List=[[NSMutableArray alloc] init];
self.List=[[NSMutableArray arrayWithArray:[DataClass returnList:sql]]retain];

第一个alloc-init完全没必要。如果属性合理,它不会产生泄漏,但它没有任何意义。删除这两行中的第一行。

此外,您的returnList:方法返回一个字符串,但您在上面引用的第二行中将其用作数组。

总而言之,您的代码中存在相当多的逻辑错误。您可能希望通过调试器和分析器运行它(菜单Product - Analyze)。