0

我遇到了 ARC 的问题。它不保留 webview。场景是我必须将 webview 从一个视图控制器发送到另一个视图控制器。原因是当用户搜索我想将他带到带有其他选项的新屏幕时。(我必须使用相同的 webview)

这是示例代码:我有一个 ViewController1,它有一个 webview(我在 xib 中添加了它。)我正在加载说 google,一旦用户搜索某些内容并且完成加载后,我必须将他带到一个新的视图控制器并在新的视图控制器中显示相同的 webview。

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

在第二个视图控制器中,我在延迟 10 秒后加载 stackoverflow.com。问题是它可以很好地加载stackoverflow,但它没有调用任何委托方法。为什么?

@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 保留了 webview,但没有调用委托方法。为什么?

谢谢赛

4

2 回答 2

3

ViewController1 delloc 方法导致了问题:

如果我取消注释 self.textWebView.delegate = nil 它工作正常。原因是首先我们为 newViewController 设置 webview,然后在 ViewController1 的 dealloc 中我们将其委托设置为 nil。

- (void)dealloc{
    [self.testWebView stopLoading];
    if(self.testWebView.delegate == self)
        self.testWebView.delegate = nil;
    self.testWebView = nil;
}
于 2012-10-05T19:10:35.253 回答
0

我注意到的第一件事是您在合成属性时没有指定实例变量名称。那只是要求碰撞。这是一个应该看起来如何的示例:

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


@implementation ViewController1

@synthesize testWebView=_testWebView;

此外,我注意到在ViewController1中您使用了IBOutlet,因此所有内容都可能在 Interface Builder 中连接起来。尝试确保在 Interface Builder 中设置委托属性,因为您没有在实现中设置它。这就是为什么您没有收到任何消息的原因。

ViewController2看起来像您在代码中设置了委托。问题是,您没有IBOutlet在属性前面。通常这意味着您只需在代码中设置 WebView,但在您的示例中,您永远不会创建 UIWebView 控件的新实例并将其分配给 self.testWebView。这意味着如果它确实显示在页面上,那是因为使用了 Interface Builder 来创建它。如果不在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];
}

希望这会有所帮助,我必须查看您的完整实施才能获得比这更具体的信息。

于 2012-05-31T02:47:46.537 回答