繁体   English   中英

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

[英]When should I release my array?

我正在从互联网解析一些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;
    }

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

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

self.items = [NSMutableArray array];

释放它的正确点是dealloc

如果你:你可能不想立即释放它:

  • 使用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

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

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

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

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

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

.h班

@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];
}

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

your statement items=[[NSMutableArray alloc] init];

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

所以在viewDidLoad以这种方式使用

NSMutableArray *tempArray=[[NSMutableArray alloc] init];
self.items=tempArray;
[tempArray release];

然后在dealloc释放你的items数组,并在viewDidUnload中将其设置为nil

- (void)viewDidUnload {
    [super viewDidUnload];
    self.items=nil;
}

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

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

根据Apple的UITableView reloadData方法文档

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

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

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

第二,因为作为一个属性可以确保先前的值会被释放,如果你碰巧分配一个新的价值items

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM