在同一个.m文件中重用NSString

时间:2009-12-19 02:50:43

标签: iphone nsstring

我有一个字符串(目前在我的.h文件中定义),我想在我的.m文件中填写并重用。

以下是设置:

  1. 用户点击我界面中的btnA
  2. btnA运行一个方法(buttonAClicked),将NSString的值设置为“foo”
  3. USer点击我界面中的btnB
  4. btnB运行一个返回NSString值的方法(buttonBClicked)(例如:“foo”)
  5. 用户再次点击btnA,该方法将NSString更新为“新值”......
  6. 利润!
  7. 以下是一些代码:

    /* Modal_TestAppDelegate.h */
    // in the @interface block //
    @public
    NSString *countOfMatches;
    // in the main area of the .h //
    @property (nonatomic, readwrite, reatain) NSString *countOfMatches;
    /* Modal_TestAppDelegate.m */
    @synthesize countOfMatches;
    -(void)applicationDidFinishLaunching:(UIApplication *)application{
    ... other code ...
    self.countOfMatches = [[NSString alloc] initWithFormat:@"0"];
    }
    -(void)updateButtonClicked:(id)sender{
    countOfMatches = @"1";
    NSLog(@"countOfMatches is now: %@",countOfMatches);
    }
    -(void)readButtonClicked:(id)sender{
    NSLog(@"I wonder what countOfMatches is set to now? %@",countOfMatches); // CRASH!
    }
    

    “readButtonCicked区域是我崩溃的地方 - 看起来我再也看不到countOfMatches字符串。

    关于如何在单个类中简单地重用“变量”的任何想法(如果我正确地将.m实现称为“类” - 这是我的第一次尝试而且我有点扯掉页面我有几本Xcode和iPhone SDK书籍。

    谢谢!

3 个答案:

答案 0 :(得分:4)

您应该将NSString属性设置为copy,而不是retain。 (更多here

@property (nonatomic, readwrite, copy) NSString *countOfMatches;

你也在这行泄漏内存

self.countOfMatches = [[NSString alloc] initWithFormat:@"0"];

可能是

self.countOfMatches = [[[NSString alloc] initWithFormat:@"0"] autorelease];

甚至更好:

self.countOfMatches = [NSString stringWithFormat:@"0"];

甚至是最好的(实际上, 应该是什么):

self.countOfMatches = @"0";

使用NSString的任何“格式”方法都没有意义 - 您只需将其设置为静态字符串。

答案 1 :(得分:0)

当您将countOfMatches设置为@"1"

中的字符串文字updateButtonClicked:时出现问题

字符串文字是自动释放的,这意味着当运行循环的这个传递完成后,它将收到-release消息。

当您的最顶层方法完成时,运行循环完成,这意味着您的updateButtonClicked:方法将正常工作,但是当它完成时,countOfMatches将指向垃圾内存。

如果在更新按钮之后按下读取按钮,应用程序将尝试在内存中找到countOfMatches指向的对象,并将找到垃圾。这就是你的应用程序崩溃的原因。

存在两种可能的解决方案:

  1. 通过属性访问变量,该属性将负责内存管理:
  2. self.countOfMatches = @"1";

    1. 直接访问变量并保留字符串文字:
    2. countOfMatches = [@"1" retain];

答案 2 :(得分:0)

该属性具有复制特性,因此它会复制已分配的内容,而后者又具有retain的特性(它所创建的副本的保留计数为1),因此如果它是一个字符串则无关紧要是 - 否。

但这里有一个稍微偏离主题的问题:如果你要改变这个值,为什么不将它存储为NSInteger或NSUInteger?

如果您从其他地方获取NSString,只需使用NSString方法-integerValue并存储该数字。

然后,只要您需要countOfMatches作为字符串,请使用NSNumber即时将值转换为字符串形式。这也有获得本地化字符串值的额外好处。假设self.countOfMatches现在是NSInteger:

NSString* countOfMatchesStr = [[NSNumber numberWithInteger:self.countOfMatches] descriptionWithLocale:[NSLocale currentLocale]];

任何好的Cocoa或Cocoa Touch应用程序从一开始就应该是国际化的,无论你是否打算用你正在编写它的初始语言以外的语言提供它。

这意味着至少要执行以下操作:

  • 每当您创建新的Xcode项目时,选择每个xib文件,获取信息,单击常规选项卡,然后在窗格底部单击按钮 Make文件可本地化。最好在将项目导入版本控制之前执行此操作,因为它会将xib文件从项目级别移动到名为XXXX.lproj的子文件夹中,其中XXXX是您正在使用的语言的语言代码。

  • 永远不要将面向用户的字符串文字放入源代码中!创建.strings文件:创建一个新文件。当模板窗口出现时,在Mac部分选择Resource,然后选择.strings文件。将文件命名为 Localizable.strings 并将其保存到项目中。然后一定要按照最后一个项目符号中的步骤实际使其可本地化。

  • 对于您将DID放入源代码的所有字符串文字,将它们包装到NSLocalizedString(@"My Button Label", @"an optional comment, use empty string if no comment");的调用中我将留给您阅读有关如何格式化.strings内容的更多内容文件。