什么时候应该发布我的阵列?

时间:2011-06-24 02:03:17

标签: iphone objective-c cocoa-touch memory nsarray

我正在从互联网解析一些JSON,然后将它们添加到一个数组中,该数组是我的UITableView的数据源。我不确定何时应该发布我的阵列?

.h:项目

@property(nonatomic,retain)NSMutableArray*  items;

.m:connectionDidFinishLoading

// fetch succeeded    
    NSString* json_string = [[NSString alloc] initWithData:retrievedData encoding:NSUTF8StringEncoding];

    //Check ST status
    int status =  [[[[json_string objectFromJSONString] valueForKey:@"response"] valueForKey:@"status"]intValue];
    //NSLog(@"Status: %d", status);

    items = [[NSMutableArray alloc] init];
    NSDictionary* messages = [[NSDictionary alloc] init]; 

    switch (status) {
        case 200:
            messages = [[[json_string objectFromJSONString] valueForKey:@"messages"] valueForKey:@"message"];

            for (NSDictionary *message in messages)
            {
                [items addObject:message];
            }
            [self.tableView reloadData];
        break;

        default:
        break;
    }

7 个答案:

答案 0 :(得分:9)

其一,如果您打算在其上调用items,则可能需要将NSMutableArray声明为addObject:的实例。

两,将它声明为属性,这样如果你最终获得它多次,那么当你这样做时会释放旧的值。

self.items = [NSMutableArray array];

释放它的正确点是dealloc

答案 1 :(得分:2)

如果您:

,可能您不想立即发布
  • 使用didSelectRowAtIndexPath:方法获取详细信息视图并将此数据传递给他们
  • 在cellForRowAtIndexPath中定义自定义UITableViewCell样式:方法
  • 在其他地方使用此数据

最佳做法是声明一个实例变量并在.m中合成它,在适当的操作中使用并在dealloc方法中释放。

您可以使用的一个可能的发布点是刷新表格中显示的数据。

实施例

我从应用程序中的API中获取数组中的字典并使用类似的东西。

MyTableViewController.h

@interface MyTableViewController {
    NSMutableArray *items;
}

@property (nonatomic, retain) NSMutableArray *items;

@end

MyTableViewController.m

@implementation MyTableViewController

@synthesize items;

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [items count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *cellIdentifier = @"FilesCellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
    }

    cell.textLabel.text = [[items objectAtIndex:indexPath.row] valueForKey:@"name"];
    cell.imageView.image = [UIImage imageNamed:[[NSString alloc] initWithFormat:@"filetype_%@.png", [[items objectAtIndex:indexPath.row] valueForKey:@"type"]]];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
        MyDetailViewController *detailViewController = [[MyDetailViewController alloc] initWithNibName:@"MyDetailViewController" bundle:[NSBundle mainBundle]];
        detailViewController.item = [items objectAtIndex:indexPath.row];
        [self.navigationController pushViewController:detailViewController animated:YES];
        [detailViewController release];
        detailViewController = nil;
    }
}

- (void)getItems
{
    [items release];
    items = [[NSMutableArray alloc] init];

    //Do some requests here

    for (NSDictionary *dict in results)
    {
        [items insertObject:dict atIndex:0];
    }

    [self.tableView reloadData];
    [self stopLoading];
}

@end

答案 2 :(得分:2)

在错误的地方释放一段时间会导致内存泄漏,在分配之前你可能会遇到像if(){[... release]}这样的情况。没有经过测试但是这种释放可以避免泄漏。

答案 3 :(得分:0)

最常见的是将项目变量作为类的属性,一旦您可能需要在您的tableView:cellForRowAtIndexPath:方法中使用它。

因此,将它作为属性变量,您可以在dealloc方法上释放它。

答案 4 :(得分:0)

很明显,item将使用您的数组UITableView来显示数据。

首先在.h类中将其声明为实例变量。

.h class

@interface MyClass 
{
  MSMutableArray* items;
}
@property(nonatomic,retain) MSMutableArray* items;

@end

.m 类中。

@synthesis iMyArray;

你填写数组的代码应该是

NSMutabelArray* itemsTemp = [[NSMutabelArray alloc] initWithCapacity:1];

messages = [[[json_string objectFromJSONString] valueForKey:@"messages"] valueForKey:@"message"];
[json_string release];

for (NSDictionary *message in messages) {
    NSLog(@"%@",[message valueForKey:@"body"]);
    [itemsTemp addObject:message];
}


self.items= itemsTemp;

[itemsTemp release];
itemsTemp = nil;

[self.tableView reloadData];

现在dealloc发布你的数组实例。

-(void) dealloc
{
   if(items )
   {
    [items release];
    items = nil ;
   }
   [super dealloc];
}

答案 5 :(得分:0)

正确的方法是在.h类中使它成为属性,因为你已经将它声明为属性:记住一件事总是使用self来分配属性。

您的陈述items=[[NSMutableArray alloc] init];

是错误的。(使用self)也因为你的属性retain键入使用它就增加了保留计数。这会给你一个泄漏。

所以在viewDidLoad

中使用这种方式
NSMutableArray *tempArray=[[NSMutableArray alloc] init];
self.items=tempArray;
[tempArray release];

然后在dealloc中释放您的项目数组,并在viewDidUnload

中将其设置为nil
- (void)viewDidUnload {
    [super viewDidUnload];
    self.items=nil;
}

- (void)dealloc {
    [self.items release];
[super dealloc];
}

希望你现在可以理解你应该如何使用它。

答案 6 :(得分:0)

根据Apple的documentation of UITableView reloadData method

“[...]为提高效率,表格视图仅重新显示那些可见的行”

这意味着只要表格被使用,你就不应该释放items数组,即你必须将数组声明为属性。

首先,因为如果滚动视图,您仍然需要items信息才能显示下方或上方的行。

第二,因为作为一个属性,如果您碰巧将新值分配给items,则可以确保释放先前的值。

最后,释放属性的常见位置在dealloc方法中,具体取决于您在viewDidUnload方法中的实现。