Просить WebView загрузить веб-страницу из другого класса

У меня есть WebView, который мне нужно попросить загрузить веб-сайт из другого класса. Поэтому я реализовал следующую функцию:

-(void)performResearch:(NSString *)aString {  
    NSLog(@"Received Request!");  
    [[researcher mainFrame]
    loadRequest:[NSURLRequest
    requestWithURL:[NSURL URLWithString:aString]]]; 
}

В моем другом классе я вызываю функцию следующим образом:

Researcher *res = [[Researcher alloc] init];
[res performResearch:@"http://www.twitter.com"];
[res release];

Я не получаю ошибок компилятора, и NSLog действительно вызывается, однако WebView не загружает веб-страницу. Ошибок в журнале тоже нет. Я озадачен.

Может ли кто-нибудь сказать мне, что случилось?


person Pripyat    schedule 27.02.2010    source источник


Ответы (2)


Вы не показываете, где объявлено researcher, но оно выглядит как обычная переменная экземпляра. Откуда берется ценность?

Если оно приходит из-за пределов класса Researcher, то оно выглядит как nil, потому что ваш другой класс создает новый экземпляр Researcher, но не предоставляет атрибут researcher. Если вы передаете сообщения объектам nil, сообщение игнорируется. Вот почему вы не получаете ошибку. Попробуйте разбить строку запроса загрузки на несколько строк и записать значения объектов.

РЕДАКТИРОВАТЬ:

Интерфейсный Разработчик устанавливает атрибут UIWebView одного конкретного экземпляра класса Researcher. Чтобы обновить это веб-представление, вам нужно вызвать performResearch в том же экземпляре. Вы не можете использовать новый экземпляр, потому что он вообще не будет подключен к веб-представлению.

Если возможно, вы должны передать исходный объект Researcher новому классу и использовать его вместо этого:

[self.researcher performResearch:@"http://www.twitter.com"];
person Colin Gislason    schedule 27.02.2010
comment
Объявлен исследователь здесь: @interface Researcher : NSObject { в файле с именем Researcher.h. Я хочу получить к нему доступ через другой файл. - person Pripyat; 27.02.2010
comment
Я имею в виду этого исследователя в методе performResearcher: [researcher mainFrame] - person Colin Gislason; 27.02.2010
comment
Как я могу передать исходный объект новому классу? Я никогда не делал этого раньше :/ - person Pripyat; 27.02.2010
comment
Вы должны найти объект или метод, где доступен исходный объект, и вы можете передать его туда, где вы создаете новый класс. т. е. ваш контроллер представления может содержать объект A, который создает объект B, которому необходимо вызвать performResearch. Вам нужно будет передать объект Researcher из контроллера представления в объект A, который передаст его объекту A. Затем объект A сможет его использовать. Если это невозможно, может помочь синглтон (вы можете поискать в переполнении стека, как это сделать). - person Colin Gislason; 27.02.2010
comment
Я исправил это с помощью sharedInstance. Теперь он отлично работает! :-) - person Pripyat; 28.02.2010

-(void)performResearch:(NSString *)aString {  
    NSLog(@"Received Request!");  
    [[researcher mainFrame]
    loadRequest:[NSURLRequest
    requestWithURL:[NSURL URLWithString:aString]]]; 
}

В моем другом классе я вызываю функцию следующим образом:

Researcher *res = [[Researcher alloc] init];
[res performResearch:@"http://www.twitter.com"];
[res release];

В пределах performResearch: объект, которому вы отправили сообщение performResearch: в последнем коде, — это self. researcher — какая-то другая переменная; вы разговариваете с другим объектом, который, вероятно, не является этим Исследователем.

В ваш комментарий к ответу Колина Гисласона, вы говорите, что researcher не Researcher, а WebView. Было бы неплохо исправить этот неточный выбор имени переменной.

После того, как вы переименовали переменную во что-то более точное, например webView, вам нужно убедиться, что в ней что-то есть. Простое наличие переменной бесполезно; вам нужно иметь указатель на объект в переменной. В противном случае указатель в переменной равен nil, а сообщения в nil вообще ничего не делают. Они не падают, не терпят неудачу, не достигают успеха, не ломаются — выполнение продолжается, как будто ничего не произошло, потому что оно произошло.

Вы говорите, что переменная является IBOutlet; это означает, что вы хотите подключить розетку в IB. Одной из возможных причин вашей проблемы является то, что вы забыли это сделать, что объясняет переменную, содержащую nil. Убедитесь, что он подключен в IB.

Другая возможная причина вашей проблемы заключается в том, что этот наконечник не был загружен. Если объект Researcher владеет пером, то, как правило, он несет ответственность за его загрузку, а это значит, что вам нужно это сделать. Если какой-то другой объект загружает перо с Researcher и WebView, то ваше создание другого объекта Researcher в последнем фрагменте кода неверно; этот второй объект Researcher не имеет отношения к объекту в nib и не имеет WebView из какого-либо источника. В этом последнем случае вам придется вырезать создание объекта Researcher и использовать тот, что в nib.

Это последнее решение может потребовать добавления выхода к объекту, класс которого содержит второй фрагмент кода. Я не одобряю это решение. Трудно сказать, что вам следует делать, потому что я не уверен, где объекты Researcher вписываются в триумвират MVC. Я подозреваю, что вам нужно еще немного подумать о том, к какой категории он относится; Я думаю, что это должен быть Контролер, и что вам нужно будет сделать некоторый рефакторинг, чтобы восстановить границы, которые вы должны иметь между полномочиями.

Неспособность поддерживать MVC в вашем приложении обычно приводит к тому, что Cocoa становится сложнее использовать, чем обычно.

person Peter Hosey    schedule 27.02.2010
comment
Я думаю, что проблема в том, что я не использую один и тот же экземпляр... Теперь мне нужно выяснить, как передать исходный объект в новый класс... - person Pripyat; 27.02.2010
comment
Дэвид Шифер: См. мой предпоследний абзац. - person Peter Hosey; 27.02.2010