Повторное использование NSString в том же файле .m - PullRequest
0 голосов
/ 19 декабря 2009

У меня есть строка (в настоящее время определенная в моем файле .h), которую я хотел бы заполнить и повторно использовать в моем файле .m.

Вот настройки:

  1. Пользователь нажимает btnA в моем интерфейсе
  2. btnA запускает метод (buttonAClicked), который устанавливает значение NSString в «foo»
  3. Пользователь нажимает btnB в моем интерфейсе
  4. btnB запускает метод (buttonBClicked), который возвращает значение NSString (например: "foo")
  5. Пользователь снова щелкает btnA, и метод обновляет строку NSString «новое значение» ...
  6. Profit!

Вот код:

/* 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 ]

4 голосов
/ 19 декабря 2009

Вам следует установить свойство NSString на copy, а не retain. (Подробнее здесь )

@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 - вы просто устанавливаете его в статическую строку.

0 голосов
/ 21 февраля 2010

Свойство имеет характеристику копирования, поэтому оно создает копию того, что ему назначено, что, в свою очередь, имеет характеристику сохранения (копия, которую оно создает, имеет счет сохранения 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, получите информацию о нем, щелкните вкладку General и в нижней части панели нажмите кнопку Make File Localizable . Это лучше сделать перед импортом проекта в систему управления версиями, поскольку он перемещает файл xib с уровня проекта в подпапку с именем XXXX.lproj, где XXXX - это код языка, на котором вы работаете.

  • Никогда не вставляйте строковые литералы в свой исходный код! Создайте файл .strings: создайте новый файл. Когда откроется окно шаблона, в разделе Mac выберите Resource, затем файл .strings. Назовите файл Localizable.strings и сохраните его в своем проекте. Затем обязательно следуйте инструкциям в последнем пункте, чтобы сделать его локализуемым.

  • для всех тех строковых литералов, которые вы ДЕЙСТВИТЕЛЬНО поместили в ваш исходный код, оберните их в вызовы NSLocalizedString(@"My Button Label", @"an optional comment, use empty string if no comment"); Я предоставлю вам больше информации о том, как форматировать содержимое файлов .strings.

0 голосов
/ 19 декабря 2009

Ваша проблема возникает, когда вы устанавливаете countOfMatches в строковый литерал @"1" в updateButtonClicked:

Строковые литералы автоматически высвобождаются, что означает, что после завершения этого цикла выполнения он получит сообщение -release.

Цикл выполнения завершается, когда ваш самый верхний метод завершен, что означает, что ваш updateButtonClicked: метод будет работать нормально, но когда он завершится, countOfMatches будет указывать на мусорную память.

Если вы нажмете кнопку чтения после кнопки обновления, ваше приложение попытается найти объект в памяти, на который указывает countOfMatches, и вместо этого найдет мусор. Вот почему ваше приложение падает.

Существует два возможных решения:

  1. Доступ к переменной осуществляется через свойство, которое позаботится об управлении памятью:

self.countOfMatches = @"1";

  1. Прямой доступ к переменной и сохранение строкового литерала:

countOfMatches = [@"1" retain];

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...