【问题标题】:Crash after setting WebView Delegate设置 WebView 委托后崩溃
【发布时间】:2016-12-11 18:46:24
【问题描述】:

我已经在 ViewController 中的 viewDidLoad 方法中开发了 webView

UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
id <UIWebViewDelegate> delegate =[[MyDelegate alloc] init];
webView.delegate = delegate;
NSError *error;
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];

NSString *htmlContent = [[NSString alloc] initWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:&error];
[webView loadHTMLString:htmlContent baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];

[self.view addSubview:webView];

我在 MyDelegate 类的实例上设置了委托。

在 MyDelegate 类中:

#import <UIKit/UIKit.h>

 @interface MyDelegate : NSObject <UIWebViewDelegate>

 @end



#import "MyDelegate.h"

 @implementation MyDelegate

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

    return YES;

 }
 @end

但是在启动加载过程中应用我的崩溃。 如果我没有加载 html 内容,但 url(例如“google.com”)会发生崩溃。

当我评论这个“webView.delegate = delegate;”时不会发生崩溃。

我知道我可以在 ViewController.h 中使用它:

@interface ViewController : UIViewController<UIWebViewDelegate>

这在 viewDidLoad:

webView.delegate = self;

但我需要使用其他类作为委托(不是 ViewController),但 webview 必须位于 ViewController 中。

我怎样才能做到这一点? 帮帮我!

【问题讨论】:

  • 对于其他类作为委托,您可以使用协议。
  • 感谢您的评论,但您是什么意思?我使用协议 UIWebViewDelegate。我需要使用其他协议吗?
  • 什么是崩溃信息?
  • 我没有收到任何消息。只是应用停止在线'return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));'
  • 我看到了 - 线程 1 exc_bad_access (code=1 address=0x8)

标签: ios objective-c iphone webview


【解决方案1】:
- (void)viewDidLoad {
    [super viewDidLoad];
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    id<UIWebView> delegate =(id)self;
    webView.delegate = delegate;
    NSError *error;
    NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];

    NSString *htmlContent= [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:&error];
    [webView loadHTMLString:htmlContent baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];

    [self.view addSubview:webView];
}

MyDelegate.h

#import <UIKit/UIKit.h>

@protocol UIWebView <UIWebViewDelegate>
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;


@end
@interface MyDelegate : NSObject
@end

【讨论】:

    【解决方案2】:

    在您的 ViewController 本身中,您可以实现 UIWebViewDelegate。

    -(void)viewDidLoad {

    [super viewDidLoad];
    
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    webView.delegate = self;
    
    NSError *error;
    
    NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    
    NSString *htmlContent= [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:&error];
    [webView loadHTMLString:htmlContent baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
    
    [self.view addSubview:webView];
    

    }

    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    return YES;
    

    }

    【讨论】:

      【解决方案3】:

      让我指出根本原因。 UIWebView 的委托属性是一个弱引用(Swift 源代码中的“unowned(unsafe)”),这意味着它的内存可以随时释放。

      因此,要解决这个问题,您必须将对控制器的引用作为类属性保留。

      在 Swift 中成功测试的解决方案示例:

      class MyUIViewController : UIViewController{
          let leftDelegate:MyWebViewDelegate = MyWebViewDelegate()
          ...
      }
      

      【讨论】:

        【解决方案4】:

        我发布了一个单独的答案,因为我认为有必要提供明确的 Objective-C 解决方案,因为 OP 可能会错过 David GONZALEZ 的答案,因为它是在 Swift 中,尽管他绝对做到了。

        问题在于,当 Web 视图调用其委托时,该委托已被释放。所以解决方案是将MyDelegate类型的属性添加到ViewController私有扩展声明:

        @interface ViewController ()
        @property (nonatomic, strong) MyDelegate* webViewDelegate;
        @end
        

        然后将在-viewDidLoad中创建的MyDelegate实例存储在该属性中:

        ...
        id <UIWebViewDelegate> delegate =[[MyDelegate alloc] init];
        webView.delegate = delegate;
        self. webViewDelegate = delegate;
        ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多