#iphone #objective-c
#iPhone #objective-c
Вопрос:
слушатель долгое время, вызывающий впервые.
У меня основная проблема с памятью, которую я не понимаю, и я уверен, что почти любой из вас увидит через секунду. Я играю, пытаясь изучить различные способы использования UIWebViews, получения строк из URL-адресов и так далее. В частности, я пытаюсь получить один URL-адрес из другого. Другими словами, я загрузил HTML-страницу в Интернет, содержащую URL. Адрес этой страницы закодирован в приложении, что дает мне «зацепку» в приложении — я могу изменить содержимое этой страницы и отправить приложению новый URL в любое время, когда захочу. Имеет смысл?
Итак … извлекаем URL? Нет проблем. Передача его в строку для последующего использования — без проблем. Но когда я настраиваю распознаватель жестов касания, который должен принимать эту строку, преобразовывать ее обратно в NSURL и открывать ее в Safari, я получаю сбой во время выполнения. Вызов NSLog сообщает мне, что рассматриваемая строка продолжает присваиваться всевозможным случайным объектам.
Далее следуют соответствующие фрагменты моего кода. Я уверен, что некоторые из вас скажут мне, что есть гораздо лучшие способы делать то, что я хочу, — и это, безусловно, приветствуется. Но мне также очень хотелось бы знать, что я делаю неправильно для этой конкретной реализации, поскольку я уверен, что это основное недоразумение, которое я хотел бы исправить.
Заранее спасибо. (И извините за форматирование блока кода — не совсем освоился с публикацией здесь!)
#import "Messing_With_Web_ViewsViewController.h"
@implementation Messing_With_Web_ViewsViewController
@synthesize tapView;
NSString *finalURL;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *firstString = @"http://www.my_web_address.html";
//Of course, I have the correct address here.
NSURL *firstUrl = [NSURL URLWithString:firstString];
NSError * error;
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:amp;error];
if ( finalURL )
{
NSLog(@"Text=%@", finalURL);
//everything fine up to here; console prints the correct
contents of "my web address"
}
else
{
NSLog(@"Error = %@", error);
}
//Taps
UITapGestureRecognizer *tapRecognizer;
tapRecognizer=[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(foundTap:)];
tapRecognizer.numberOfTapsRequired=1;
tapRecognizer.numberOfTouchesRequired=1;
[tapView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
}
- (void)foundTap:(UITapGestureRecognizer *)recognizer {
NSLog(@"Trying to load %@", finalURL);
//at this point the app either crashes, or the console shows a random memory object
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: finalURL]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[finalURL release];
[super dealloc];
}
@end
Ответ №1:
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:amp;error];
Строка выше создает экземпляр NSString, которым вы не владеете (потому что вы не вызывали метод, имя которого включает ‘new’, ‘alloc’ ‘retain’ или ‘copy’ для него). Поэтому это finalURL
с в конечном итоге будет уничтожено, когда оно больше не понадобится. К моменту выполнения вашего -foundTap:
метода finalURL
он был освобожден, и вы просто ссылаетесь на ячейку памяти, где она была раньше и которая теперь может содержать какой-либо другой объект или случайные данные.
Еще раз прочитайте руководство по управлению памятью, а также научитесь запускать статический анализатор, который должен указывать на подобные ошибки.