Объект ObjC изменяется на случайные объекты: проблема с памятью

#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 он был освобожден, и вы просто ссылаетесь на ячейку памяти, где она была раньше и которая теперь может содержать какой-либо другой объект или случайные данные.

Еще раз прочитайте руководство по управлению памятью, а также научитесь запускать статический анализатор, который должен указывать на подобные ошибки.