非常感谢@Hot Licks的帮助,他指出我的sqlite3代码有什么问题.我修改了代码,sqlite3增加的实时字节消失了.
对于其他新的ios开发人员也可能面临这个问题,我将原始问题留在后半部分.
我的新问题是:仪器中的每一代之间仍然存在一些增加的实时字节,但似乎所有对象都是由ios SDK代码构成的,而不是我的代码.那么我应该单独增加,不需要担心吗?
@Hot Licks说我操作UI的方式可能有问题,所以我详细描述它:
1)我在Xcode 5中为ipad创建了一个主细节应用程序;
2)使主控器嵌入标签栏控制器,并添加一个新选项卡,因此主控制器是一个带有2个选项卡的标签栏控制器.所有这些都是在故事板中完成的.
3)删除详细控制器中的默认标签.在详细视图中添加tableview,textview和3个按钮.在tableview中添加原型单元格.所有这些都是在故事板中完成的.
4)在tableViewController.h中连接tableview,textview作为插座.
@property (strong, nonatomic) IBOutlet UITableView *tableView; @property (strong, nonatomic) IBOutlet UITextView *explanationText;
5)修改功能:主控制器中的"tableview:didSelectRowAtIndexPath":
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ LHBPoetry *poetry = [_searchResults objectAtIndex:indexPath.row]; self.detailViewController.poetryId = poetry.poetryId; }
6)修改详细视图控制器中的代码,请在后半部分查看"详细控制器代码的相关片段"
它有问题吗?
非常感谢帮助!!!
较旧的部分:
当我调试我的应用程序时,在模拟器中,内存(实时字节)不断增加,但仪器中没有泄漏.
我的问题是:
我的代码出了什么问题?我想也许每次点击一个项目,都会重新创建细节的界面?
如何找到泄漏的代码?
由于一些爱好者的帮助,我将我的问题缩小到从sqlite3获取数据的代码.这些代码有什么问题?
我创建了一个默认的主 - 详细信息应用程序,我多次单击master中的项目,其实时字节也会增加.这是否意味着我不需要担心这个问题?
我的应用程序是一个主要的细节应用程序,使用ARC,SDK是iOS 7,使用Xcode 5编写代码.
这个应用程序在做什么:在左主导航中,有许多项目,在右侧详细视图中有一个表格.当用户单击某个项目时,详细信息视图中表格的内容将会更改.
问题是每次我点击主导航中的一个项目,内存将增加约150K~300K.
码:
主控制器代码的相关片段:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ LHBPoetry *poetry = poetryArray[indexPath.row]; self.detailViewController.poetryId = poetry.poetryId; }
细节控制器代码的相关片段:
@interface LHBDetailViewController (){ LHBPoetry *poetry; NSArray *sentenceArray; PoetryDao *poetryDao; PoetryService *poetryService; } @property (strong, nonatomic) UIPopoverController *masterPopoverController; - (void)configureView; @end @implementation LHBDetailViewController #pragma mark - Managing the detail item - (void)setPoetryId:(int)poetryId { if (_poetryId != poetryId) { _poetryId = poetryId; // Update the view. [self configureView]; } if (self.masterPopoverController != nil) { [self.masterPopoverController dismissPopoverAnimated:YES]; } } - (void)configureView { // Update the user interface for the detail item. if (self.poetryId > 0) { poetry = [poetryDao getPoetryById:self.poetryId]; }else{ poetry = [poetryDao getPoetryById:1]; } if(poetry != nil){ //custom title if(poetry.dynasty != nil){ self.title = [NSString stringWithFormat:@"%@ [%@]%@", poetry.name, poetry.dynasty, poetry.author]; }else{ self.title = [NSString stringWithFormat:@"%@ %@", poetry.name, poetry.author]; } //refresh sentenceArray sentenceArray = [poetryService changeStringToArray:poetry.content withSplitter:[LHBConstant getPoetrySplitter]]; }else{ //custom title self.title = @""; } [_tableView reloadData]; } - (void)viewDidLoad { [super viewDidLoad]; poetryDao = [[PoetryDao alloc] init]; poetryService = [[PoetryService alloc] init]; [self configureView]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"detailCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Configure the cell... NSString *sentence = sentenceArray[indexPath.row]; cell.textLabel.text = sentence; return cell; } @end
我读了一篇关于使用Heapshot Analysis查找泄漏的文章.
在Xcode中,我使用Product-> Profile,打开乐器,然后选择Memory - > Allocations.然后我这样做:
在乐器中,单击"标记生成";
在我的应用中,单击主视图中的项目.多次重复这两个步骤.
我从乐器得到了结果.
开了一代,我明白了.
我比较了所有代,我发现每次单击主导航中的项目时对象都会增加.
它指向sqlite3的代码:
以下是代码片段:
-(LHBPoetry *) getPoetryById:(int) poetryId{ sqlite3 *database; @try{ //open database if(sqlite3_open([[LHBConstant dataFilePath] UTF8String], &database)!=SQLITE_OK){ sqlite3_close(database); NSAssert(0, @"Failed to open database."); } //find in database NSString *query = @"SELECT id,name,author,dynasty, content, explanation, has_license, has_mastered FROM poetry where id = ?"; sqlite3_stmt *statement; if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)==SQLITE_OK){ //bind parameter sqlite3_bind_int(statement, 1, poetryId); while (sqlite3_step(statement)==SQLITE_ROW) { int primaryId = sqlite3_column_int(statement, 0); char *name = (char *)sqlite3_column_text(statement, 1); char *author = (char *)sqlite3_column_text(statement, 2); char *dynasty = (char *)sqlite3_column_text(statement, 3); char *content = (char *)sqlite3_column_text(statement, 4); char *explanation = (char *)sqlite3_column_text(statement, 5); int hasLicense = sqlite3_column_int(statement, 6); int hasMastered = sqlite3_column_int(statement, 7); NSString *nameNS = [NSString stringWithUTF8String:name]; NSString *authorNS = [NSString stringWithUTF8String:author]; NSString *dynastyNS = dynasty == nil ? NULL : [NSString stringWithUTF8String:dynasty]; NSString *contentNS = [NSString stringWithUTF8String:content]; NSString *explanationNS = explanation == nil ? NULL : [NSString stringWithUTF8String:explanation]; LHBPoetry *poetry = [[LHBPoetry alloc] initWithId:primaryId withName:nameNS withAuthor:authorNS withDynasty:dynastyNS withContent:contentNS withExplanation:explanationNS withLicense:hasLicense withMastered:hasMastered]; return poetry; } sqlite3_finalize(statement); }else{ NSLog(@"poetry getPoetryById fail. database is not ready."); } } @catch (NSException *e) { NSLog(@"%@", e); } @finally { sqlite3_close(database); } return nil; }
并且该方法dataFilePath
中LHBConstant
的是:
+(NSString *)dataFilePath{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; documentDirectory = [documentDirectory stringByAppendingString: @"/p140107"]; return documentDirectory; }
我还在仪器中使用"记忆 - >泄漏"模板,没有泄漏.
有人可以帮帮我吗?非常感谢!