• 内存泄漏mac,xcode


    遇到这么一个泄漏事件:

    环境:Xcode 4.2.1,mac 10.7.1

    先看代码:

    .h

    View Code
    1 @interface TableController : UITableViewController
    2 
    3 @property (nonatomic ,retain) NSArray *DataSource;
    4 
    5 @end


    .m

      1 #import "TableController.h"
      2 #import "TableView.h"
      3 #import "CellItem.h"
      4 #import "Et.h"
      5 
      6 #import "DetailController.h"
      7 
      8 @implementation TableController
      9 
     10 @synthesize DataSource = _DataSource;
     11 
     12 - (void)defaultValues
     13 {
     14     self->_DataSource = nil;
     15 }
     16 
     17 - (void)loadDatasFromDB
     18 {
     19     if (self->_DataSource)
     20         [self->_DataSource release];
     21     self->_DataSource = nil;
     22 
     23     // load data from db
     24     // test code b
     25     NSMutableArray *mutDatas = [[NSMutableArray alloc] init];
     26     
     27     for (int i=0; i<10; i++)
     28     {
     29         Et *item = [[Et alloc] init];
     30         item.ID = i;
     31         item.RecordDate = [NSDate date];
     32         item.Content = [NSString stringWithFormat:@"%d,%@",i ,item.RecordDate];
     33         
     34         [mutDatas addObject:item];
     35         
     36         [item release];
     37     }
     38     
     39     self->_DataSource = [[NSArray alloc] initWithArray:mutDatas];
     40     [mutDatas removeAllObjects];
     41     [mutDatas release];
     42     mutDatas = nil;
     43     // test code e
     44 }
     45 
     46 - (void)gotoView:(id)sender
     47 {
     48     DetailController *detailViewController = [[DetailController alloc] init];
     49     [self.navigationController pushViewController:detailViewController animated:YES];
     50     [detailViewController release];
     51 }
     52 
     53 - (void)navSetting
     54 {
     55     self.navigationItem.title = @"Title";
     56     
     57     UIBarButtonItem *btnSettings
     58     = [[UIBarButtonItem alloc] initWithTitle:@"+"
     59                                        style:UIBarButtonItemStyleBordered
     60                                       target:self
     61                                       action:@selector(gotoView:)];
     62     self.navigationItem.rightBarButtonItem = btnSettings;
     63     [btnSettings release];
     64 }
     65 
     66 - (id)init
     67 {
     68     self = [super init];
     69     if (self)
     70     {
     71         [self defaultValues];
     72     [self loadDatasFromDB];/// ------注意:LeakProblem
     73     }
     74     
     75     return self;
     76 }
     77 
     78 - (id)initWithStyle:(UITableViewStyle)style
     79 {
     80     self = [super initWithStyle:style];
     81     if (self) {
     82         // Custom initialization
     83         [self defaultValues];
     84     [self loadDatasFromDB];/// ------注意:LeakProblem
     85     }
     86     return self;
     87 }
     88 
     89 - (void)dealloc
     90 {
     91     if (self.DataSource)
     92         [self->_DataSource release];
     93     
     94     [self defaultValues];
     95     
     96     [super dealloc];
     97 }
     98 
     99 - (void)didReceiveMemoryWarning
    100 {
    101     // Releases the view if it doesn't have a superview.
    102     [super didReceiveMemoryWarning];
    103     
    104     // Release any cached data, images, etc that aren't in use.
    105 }
    106 
    107 #pragma mark - View lifecycle
    108 
    109 - (void)loadView
    110 {    
    111     TableView *v = [[TableView alloc] init];
    112     v.dataSource = self;
    113     v.delegate = self;
    114     self.view = v;
    115     [v release];
    116 }
    117 
    118 - (void)viewDidLoad
    119 {
    120     [super viewDidLoad];
    121 
    122     // Uncomment the following line to preserve selection between presentations.
    123     // self.clearsSelectionOnViewWillAppear = NO;
    124  
    125     // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    126     // self.navigationItem.rightBarButtonItem = self.editButtonItem;
    127     [self navSetting];
    128     
    129     [self loadDatasFromDB];/// ------注意:LeakProblem 修复方式
    130 }
    131 
    132 - (void)viewDidUnload
    133 {
    134     [super viewDidUnload];
    135     // Release any retained subviews of the main view.
    136     // e.g. self.myOutlet = nil;
    137     
    138     if (self->_DataSource)
    139         [self->_DataSource release];
    140     self->_DataSource = nil;
    141 }
    142 
    143 - (void)viewWillAppear:(BOOL)animated
    144 {
    145     [super viewWillAppear:animated];
    146 }
    147 
    148 - (void)viewDidAppear:(BOOL)animated
    149 {
    150     [super viewDidAppear:animated];
    151 }
    152 
    153 - (void)viewWillDisappear:(BOOL)animated
    154 {
    155     [super viewWillDisappear:animated];
    156 }
    157 
    158 - (void)viewDidDisappear:(BOOL)animated
    159 {
    160     [super viewDidDisappear:animated];
    161 }
    162 
    163 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    164 {
    165     // Return YES for supported orientations
    166     return (interfaceOrientation == UIInterfaceOrientationPortrait);
    167 }
    168 
    169 #pragma mark - Table view data source
    170 
    171 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    172 {
    173 //#warning Potentially incomplete method implementation.
    174     // Return the number of sections.
    175     if (self.DataSource)
    176         return 1;
    177     return 0;
    178 }
    179 
    180 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    181 {
    182 //#warning Incomplete method implementation.
    183     // Return the number of rows in the section.
    184     if (self.DataSource)
    185         return self.DataSource.count;
    186     return 0;
    187 }
    188 
    189 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    190 {
    191     static NSString *CellIdentifier = @"Cell";
    192     
    193     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    194     if (cell == nil) 
    195     {
    196         cell = [[[CellItem alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    197         
    198         if (self.DataSource)
    199         {
    200             if (self.DataSource.count > indexPath.row)
    201             {
    202                 id cellData = [self.DataSource objectAtIndex:indexPath.row];
    203                 
    204                 if ([cellData isKindOfClass:[Et class]])
    205                 {
    206                     Et *etItem = (Et *)cellData;
    207                     
    208                     CellItem *c = (CellItem *)cell;
    209                     
    210                     if (etItem.RecordDate)
    211                     {
    212                         NSRange range;
    213                         range.location = 0;
    214                         range.length = 10;
    215                         [c.LblRecordDate setText:[[NSString stringWithFormat:@"%@" ,etItem.RecordDate] substringWithRange:range]];
    216                     }
    217                     
    218                     if (etItem.Content)
    219                     {
    220                         NSRange range;
    221                         range.location = 0;
    222                         if (etItem.Content.length >10)
    223                             range.length = 10;
    224                         else
    225                             range.length = etItem.Content.length;
    226                         [c.LblSimpleContent setText:[etItem.Content substringWithRange:range]];
    227                     }
    228                     
    229                     if (c.LblRecordDate)
    230                         [c addSubview:c.LblRecordDate];
    231                     
    232                     if (c.LblSimpleContent)
    233                         [c addSubview:c.LblSimpleContent];
    234                 }
    235                 
    236             }
    237         }
    238     }
    239     
    240     return cell;
    241 }
    242 
    243 /*
    244 // Override to support conditional editing of the table view.
    245 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
    246 {
    247     // Return NO if you do not want the specified item to be editable.
    248     return YES;
    249 }
    250 */
    251 
    252 /*
    253 // Override to support editing the table view.
    254 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    255 {
    256     if (editingStyle == UITableViewCellEditingStyleDelete) {
    257         // Delete the row from the data source
    258         [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    259     }   
    260     else if (editingStyle == UITableViewCellEditingStyleInsert) {
    261         // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    262     }   
    263 }
    264 */
    265 
    266 /*
    267 // Override to support rearranging the table view.
    268 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
    269 {
    270 }
    271 */
    272 
    273 /*
    274 // Override to support conditional rearranging of the table view.
    275 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
    276 {
    277     // Return NO if you do not want the item to be re-orderable.
    278     return YES;
    279 }
    280 */
    281 
    282 #pragma mark - Table view delegate
    283 
    284 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    285 {
    286     // Navigation logic may go here. Create and push another view controller.
    287     /*
    288      <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
    289      // ...
    290      // Pass the selected object to the new view controller.
    291      [self.navigationController pushViewController:detailViewController animated:YES];
    292      [detailViewController release];
    293      */
    294     
    295     NSLog(@"%d" ,indexPath.row);
    296 }
    297 
    298 @end

    代码中/// ------注意:LeakProblem和/// ------注意:LeakProblem 修复方式 两处语句互斥,不同时存在

    保留/// ------注意:LeakProblem,删除/// ------注意:LeakProblem 修复方式
    使用Analyze工具分析,没有泄漏代码
    使用Profile工具分析,会出现loadDatasFromDB中一个NSArray数组以及10个内容泄漏

    在调试中,尝试关闭loadDatasFromDB,在applicationDelegate.m中定义一个数组,赋予给属性Datasource,分别用上述工具再次分析,发现无泄漏

    思考再三,移出在init中对loadDatasFromDB函数的调用,在viewDidLoad中调用
    就是:
    删除/// ------注意:LeakProblem,保留/// ------注意:LeakProblem 修复方式
    又用上述工具分析,无泄漏

    至于为什么第一种方式会导致profile泄漏,暂时没有找到合适说法

    晚点再用xcode4.3.2试下【尝试了,和上述结论一样】

    2012-06-28






    无论生活、还是技术,一切都不断的学习和更新~~~努力~
  • 相关阅读:
    Redis面试题
    spring boot错误: 找不到或无法加载主类
    JAVA的高并发编程
    Redis多机多节点集群实验
    Redis单机多节点集群实验
    Redis集群概述
    Redis的持久化之AOF方式
    Redis的持久化之RDB方式
    Redis持久化介绍
    Redis Keys的通用操作
  • 原文地址:https://www.cnblogs.com/GoGoagg/p/2568428.html
Copyright © 2020-2023  润新知