Цель C - iOS - UIWebView сохраняется в ARC, но методы делегата не вызываются

У меня проблема с ARC. Это не сохранение веб-просмотра. Сценарий заключается в том, что я должен отправить веб-просмотр от одного viewcontroller к другому. Причина в том, что когда пользователь ищет что-то, я хочу вывести его на новый экран с некоторыми другими параметрами. (Я должен использовать тот же веб-просмотр)

Вот пример кода: у меня есть ViewController1, у которого есть веб-просмотр (я добавил его в xib.) Я загружаю, скажем, google в нем, и как только пользователь что-то ищет, и когда его загрузка закончится, я должен взять его с собой. просмотреть контроллер и показать то же веб-представление в новом viewcontroller.

//ViewController1
@interface ViewController1 : UIViewController <UIWebViewDelegate>
    @property (nonatomic, retain) UIWebView* testWebView;
@end

@implementation ViewController1
@synthesize testWebView;
- (void)viewDidLoad
{
    [super viewDidLoad];
    testWebView = [[UIWebView alloc]init];
    testWebView.delegate = self;
    [testWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com"]]];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
    NSString *html = [testWebView stringByEvaluatingJavaScriptFromString: 
                      @"document.body.innerHTML"];
    if ([self.testWebView.request.url.absoluteString     rangeOfString:@"output=search"].location != NSNotFound) {
        ViewController2* newViewController = [[ViewController2 alloc] init];
        [newViewController setTestWebView:self.testWebView];
        [self.navigationController setViewControllers:[NSArray arrayWithObject:newViewController] animated:NO];
    }
}
- (void)dealloc{
    [self.testWebView stopLoading];
    self.testWebView.delegate = nil;
    self.testWebView = nil;
}

Во втором контроллере представления я загружаю stackru.com после задержки 10 секунд. Проблема в том, что он нормально загружает stackru, но не вызывает ни один из методов делегата. Зачем?

@interface ViewController2 : UIViewController <UIWebViewDelegate>
    @property (nonatomic, retain) UIWebView* testWebView;
@end

@implementation ViewController2
@synthesize testWebView;
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.testWebView.delegate = self;
    [self.view addSubview:testWebView];
    [self performSelector:@selector(loadDifferentPage) withObject:nil afterDelay:10];
}

-(void)loadDifferentPage{
    [self.testWebView loadRequest:[NSURLRequest requestWithURL:[NSURL     URLWithString:@"http://www.stackru.com/"]]];
}

-(void)webViewDidStartLoad:(UIWebView *)webView{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return YES;
}

ViewController2 сохраняет веб-представление, но методы делегата не вызываются. Зачем?

Спасибо саи

2 ответа

Решение

Метод ViewController1 delloc вызывал проблему:

Если я раскомментирую self.textWebView.delegate = nil, он будет работать нормально. Причина в том, что сначала мы устанавливаем webview для newViewController, а позже в dealloc ViewController1 мы устанавливаем его делегат равным nil.

- (void)dealloc{
    [self.testWebView stopLoading];
    if(self.testWebView.delegate == self)
        self.testWebView.delegate = nil;
    self.testWebView = nil;
}

Первое, что я заметил, это то, что вы не указываете имя переменной экземпляра при синтезе свойства. Это просто просьба о столкновениях. Вот пример того, как это должно выглядеть:

@interface ViewController1 : UIViewController <UIWebViewDelegate>
    @property (nonatomic, strong) IBOutlet UIWebView* testWebView;
@end


@implementation ViewController1

@synthesize testWebView=_testWebView;

Кроме того, я заметил, что в ViewController1 вы использовали IBOutlet, так что все, вероятно, связано с Интерфейсным Разработчиком. Попробуйте убедиться, что вы установили свойство делегата в Interface Bulider, потому что вы не установили его в реализации. Вот почему вы не получаете никаких сообщений.

ViewController2 выглядит так, как будто вы задали делегата в коде. Проблема в том, что у вас нет IBOutlet перед собственностью. Обычно это означает, что вы просто настраиваете WebView в коде, но в своем примере вы никогда не создаете новый экземпляр элемента управления UIWebView и не назначаете его для self.testWebView. Это означает, что если он отображается на странице, то это потому, что для его создания использовался Interface Builder. Вы не можете установить делегат в коде, не используя IBOutlet перед объявлением testWebView, поэтому, вероятно, он не работает во втором примере.

@interface ViewController2 : UIViewController <UIWebViewDelegate>
    @property (nonatomic, strong) UIWebView* testWebView; // Mising IBOutlet
@end

@implementation ViewController2
@synthesize testWebView;
- (void)viewDidLoad
{
    [super viewDidLoad];
    // missing any code that would create the webview [[UIWebView alloc] init]
    self.testWebView.delegate = self; // You set the delegate in code here
    [self.view addSubview:testWebView];
    [self performSelector:@selector(loadDifferentPage) withObject:nil afterDelay:10];
}

Надеюсь, это поможет, мне нужно увидеть вашу полную реализацию, чтобы получить более конкретную информацию, чем эта.

Другие вопросы по тегам