【问题标题】:Memory management issues with retrieving particular lines of text from string从字符串中检索特定文本行的内存管理问题
【发布时间】:2011-12-13 05:39:52
【问题描述】:

我对 iOS 开发有点陌生。

我想从我拥有的 text(.rtf) 文件中检索字符串。该文件位于我的应用程序主包中。它的内容是:

#start word1 First word end word2 Second word end //lots of things to be added later

代码:

 path = [[NSBundle mainBundle]pathForResource:@"words" ofType:@"rtf"];
    if(path)
    {
        NSLog(@"path exists");
    }
    NSError *error = nil;

    NSString *file = [[NSString alloc]initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if(error)
    {
        NSLog(@"error");
    }
    NSString *finalword= [[NSString alloc]init ];
    NSString *startfrom = [[NSString alloc] initWithFormat:@"word%i",i+1];
    i++;
    NSLog(@"%@",startfrom);
    NSString *wordoftheday = [[NSString alloc]init ];
    NSScanner *scanner = [NSScanner scannerWithString:file];
    [scanner scanUpToString:startfrom intoString:nil];
    [scanner scanUpToString:@"end" intoString:&wordoftheday];
    finalword = [wordoftheday substringFromIndex:[startfrom length]];
    NSLog(@"%@",finalword);
    Word.text = final word;  //change label text
//[final word release];
//[wordoftheday release];
//[file release];

代码运行良好,但它给我留下了内存管理问题。如果我释放最后注释代码中的变量,应用程序会崩溃。

这个方法也在我的viewdidload中。我希望标签在用户单击按钮时更改文本。我将不得不以这种方法再次编写相同的代码,这给我留下了更多的内存问题。

【问题讨论】:

    标签: iphone objective-c ios xcode


    【解决方案1】:

    所以一一看这些,关注内存问题而不是这里的整体策略:

    NSString *finalword= [[NSString alloc]init ];

    在这里你分配/初始化一个新的不可变和空的 NSString,然后你最终会覆盖指向它的指针。你应该删除这一行。然后你需要将声明向下移动几行:

    NSString *finalword = [wordoftheday substringFromIndex:[startfrom length]];

    那么你有:

    NSString *startfrom = [[NSString alloc] initWithFormat:@"word%i",i+1];

    这个你需要稍后发布。或者只是将其更改为:

    NSString *startfrom = [NSString stringWithFormat:@"word%i",i+1];

    那么你有:

    NSString *wordoftheday = [[NSString alloc]init ];

    与结局相同的故事。除了您确实需要定义此变量以便稍后将其传递给扫描仪之外。所以改成:

    NSString *wordoftheday = nil;

    最后,您可以释放“文件”。没事儿。但是您不想发布“wordoftheday”或“finalword”,因为您不拥有这些字符串。不是您自己创建的。

    还有一个注意事项:

    if(error)

    这不是在加载“文件”时检查错误的正确方法。您应该检查该方法的返回值,然后当且仅当返回值为 nil 时才查找错误。所以将该行更改为:

    if(!file)

    (好吧,这并不是真正的内存问题,而是我注意到的一个错误。)

    我认为至少就内存问题而言,这就是全部。我希望这会有所帮助。

    【讨论】:

    • 感谢您的回答...我已将路径设为非原子并在我的界面中保留属性。这段代码中的所有其他内容都是 init .. 所以如果从 viewdidload 中剪切这段代码并用它创建一个新函数..如果我向这个函数发送多次调用会不会有任何问题,因为 path = [nsbundle...将被调用一次又一次?
    • 好吧,在这种情况下,请确保您执行 self.path=...。但是一旦你有了路径,为什么还要每次都去寻找它呢?它不会改变,是吗?当然,这会带来一个更大的问题,为什么不只加载这些单词一次并在整个应用程序中使用它们,而不是多次解析它们呢?这些是更大的问题,但我只是想解决内存管理问题。
    • 应用程序中会有很多单词......所以我不想一次加载它们......我只想更改每个按钮点击的标签文本......这就是为什么我使用函数调用来获取下一个单词。
    • 好的,好吧,取决于有多少是“许多”,我建议这可能不是更高效的解决方案。但是你应该测试它。至少考虑保留扫描仪,这样它就不必每次都重新开始。在任何情况下,至少路径不会改变(没有理由每次都要求捆绑软件找到它)并且希望您现在已经直接获得了内存管理。
    【解决方案2】:

    将这些变量作为成员变量并在dealloc中释放

    【讨论】:

    • 为什么是-1?让我知道原因
    • 对不起没有做-1 ..至于使它们成为成员变量..它将有什么好处..我将路径作为成员变量..但是如果我将每个变量都设为成员变量那么我将在函数(viewdidload 和按钮)中发送 alloc 和 init 不会有问题吗?
    • 不要使用 NSString 而是使用 NSMutableString
    • 感谢您的回答...我已将路径设为非原子并在我的界面中保留属性。这段代码中的所有其他内容都是 init .. 所以如果从 viewdidload 中剪切这段代码并用它创建一个新函数..如果我向这个函数发送多次调用会不会有任何问题,因为 path = [nsbundle...将被调用一次又一次?
    猜你喜欢
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多