简体   繁体   English

目标C-iOS-UIWebView保留在ARC中,但未调用Delegate方法

[英]Objective C - iOS - UIWebView getting retained in ARC but Delegate methods are not being called

I am having an issue with ARC. 我在使用ARC时遇到问题。 It is not retaining the webview. 它不保留Web视图。 The scenario is I have to send a webview from one viewcontroller to another one. 场景是我必须将一个WebView从一个ViewController发送到另一个ViewController。 The reason is when the user searches for something I want to take him to a new screen with some other options. 原因是当用户搜索某些我想带他到其他选项的新屏幕时。 (I have to use the same webview) (我必须使用相同的网络视图)

Here is the sample code: I have a ViewController1 which has a webview (I added it in the xib.) I am loading say google in it and once the user searches for something and when its done loading I have to take him to a new view controller and show the same webview in the new viewcontroller. 这是示例代码:我有一个ViewController1,它有一个webview(我在xib中添加了它)。我在其中加载说google,一旦用户搜索了某些内容,加载完成后,我必须将他带到新视图控制器,并在新的视图控制器中显示相同的Web视图。

//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;
}

In the second view controller I am loading stackoverflow.com after a delay of 10 secs. 在第二个视图控制器中,我在延迟10秒后加载stackoverflow.com。 The problem is it is loading stackoverflow fine, but it is not calling any of the delegate methods. 问题是它可以很好地加载stackoverflow,但是它没有调用任何委托方法。 Why? 为什么?

@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.stackoverflow.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 is retaining the webview but the delegate methods are not being called. ViewController2保留了Webview,但是未调用委托方法。 Why? 为什么?

Thanks Sai 谢赛

ViewController1 delloc method was causing the issue: ViewController1 delloc方法导致了此问题:

If I uncomment out self.textWebView.delegate = nil it works fine. 如果我取消注释self.textWebView.delegate = nil,它将正常工作。 The reason is first we are setting the webview for newViewController and later in dealloc of ViewController1 we are setting its delegate to nil. 原因是首先我们为newViewController设置了Webview,然后在ViewController1的dealloc中将其委托设置为nil。

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

First thing I noticed is you're not specifying the instance variable name when synthesizing a property. 我注意到的第一件事是在合成属性时未指定实例变量名称。 That's just asking for collisions. 那只是要求碰撞。 Here's an example of how that should look: 这是一个外观示例:

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


@implementation ViewController1

@synthesize testWebView=_testWebView;

Also, I noticed in ViewController1 you used IBOutlet so everything is probably wired up in Interface Builder. 另外,我注意到在ViewController1中您使用了IBOutlet,因此所有内容都可能在Interface Builder中进行了连接。 Try making sure that you set the delegate property in Interface Bulider because you don't set it in the implementation. 尝试确保在Interface Bulider中设置了委托属性,因为未在实现中进行设置。 That would be why you're not receiving any messages. 这就是为什么您没有收到任何消息的原因。

ViewController2 looks like you set the delegate in code. ViewController2看起来就像您在代码中设置了委托。 The problem is, you DON'T have IBOutlet in front of the property. 问题是,您在属性前面没有IBOutlet Normally this would mean that you simply setup the WebView in code, but in your example you do not ever create a new instance of a UIWebView control and assign it to self.testWebView. 通常,这意味着您只需在代码中设置WebView,但是在您的示例中,您永远不会创建UIWebView控件的新实例并将其分配给self.testWebView。 This means that if it does display on the page, it's because Interface Builder was used to create it. 这意味着如果它确实显示在页面上,那是因为使用了Interface Builder来创建它。 You couldn't set the delegate in code without using IBOutlet in front of the testWebView declaration so that's probably why it's not working in exmaple two. 如果不在testWebView声明的前面使用IBOutlet ,就无法在代码中设置委托,因此这可能就是为什么它在示例2中不起作用的原因。

@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];
}

Hope this helps, I'd have to see your full implementation to get more specific than this. 希望这会有所帮助,我将不得不看一下您的完整实现以获取比此更具体的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM