内存泄漏-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





posted @ 2012-06-28 17:32  西就东城  阅读(1204)  评论(0编辑  收藏  举报