iOS APP随着ARC没有泄漏,但实时字节增加

 大盗难过就哭_789 发布于 2023-02-06 12:00

非常感谢@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;
}

并且该方法dataFilePathLHBConstant的是:

+(NSString *)dataFilePath{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory = [paths objectAtIndex:0];
    documentDirectory = [documentDirectory stringByAppendingString: @"/p140107"];
    return documentDirectory;
}

我还在仪器中使用"记忆 - >泄漏"模板,没有泄漏.

有人可以帮帮我吗?非常感谢!

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有