2009-08-12 45 views
28

Tôi đang gặp sự cố của ứng dụng sử dụng UIWebView. Thông thường nó là khi trang không được tải đầy đủ và UIWebView được gửi bộ chọn stopLoading. Hoặc khi UIWebView tải đầy đủ trang. Tôi đã có EXC_BAD_ACCESS. Chồng trông như thế này:Tai nạn UIWebView EXC_BAD_ACCESS

#0 0x95bb7688 in objc_msgSend 
#1 0x30a671db in -[UIWebView webView:decidePolicyForNavigationAction:request:frame:decisionListener:] 
#2 0x3024a10d in __invoking___ 
#3 0x30249ff8 in -[NSInvocation invoke] 
#4 0x358ab160 in HandleDelegateSource 
#5 0x302452c1 in CFRunLoopRunSpecific 
#6 0x30244628 in CFRunLoopRunInMode 
#7 0x32044c31 in GSEventRunModal 
#8 0x32044cf6 in GSEventRun 
#9 0x309021ee in UIApplicationMain 
#10 0x0000239c in main at main.m:13 

đối với tôi điều kỳ lạ nhất ở đây là webView:decidePolicyForNavigationAction:request:frame:decisionListener: selector gửi đến UIWebView, vì không có chọn như vậy trong tài liệu hướng dẫn UIWebView! Chỉ dành cho Cocoa (không phải là ca cao chạm) WebView. Tôi nghi ngờ rằng có một cái gì đó sai với UIWebView hoặc đại biểu của nó. Nhưng tôi không thể đặt điểm ngắt để xem chúng. Vui lòng tư vấn cách tôi có thể nhận thêm thông tin trong trường hợp này.

+1

Còn về [UIWebView webView: decisionPolicyForNavigationAction: request: frame: decisionListener:] ?? – Ahsan

Trả lời

8

Thử bật NSZombie và xem có điều gì đó đang được phát hành quá sớm không.

Có thể bạn đang hủy tải chế độ xem và sau đó ngay lập tức xé phân cấp chế độ xem của bạn, gây ra điều gì đó sẽ được phát hành trước khi UIWebView được thực hiện rối tung với nó.

Trong trường hợp này, backtrace trông rõ ràng như nó là một đại biểu được phát hành sớm. Các mối quan hệ ủy nhiệm thường yếu và thiếu GC, là nguồn tuyệt vời cho các tham chiếu treo lơ lửng gây ra sự cố giống như thế này.

+0

Câu trả lời hay, điều này giúp tôi, thx. – Joey

85

Bạn phải dừng tải WebView và loại bỏ các đại biểu trước khi rời khỏi điểm:

// ARC (correct solution) 
- (void)dealloc { 
    [_webView setDelegate:nil]; 
    [_webView stopLoading]; 
} 

// non ARC 
- (void)dealloc { 
    [webView setDelegate:nil]; 
    [webView stopLoading]; 
    [webView release]; 
    [super dealloc]; 
} 

// ARC (older solution) 
- (void)viewWillUnload { 
    [webView setDelegate:nil]; 
    [webView stopLoading]; 
} 

gì Apple tài liệu đang nói: Quan trọng Trước khi phát hành một thể hiện của UIWebView mà bạn đã thiết lập một đại biểu, trước tiên bạn phải thiết lập thuộc tính ủy nhiệm của nó là nil. Điều này có thể được thực hiện, ví dụ, trong phương thức dealloc của bạn.

+0

Cảm ơn. Điều này giải quyết vấn đề EXC_BAD_ACCESS của tôi. –

+1

vui lòng trợ giúp :) – Ondrej

+3

Trong ios 6, sử dụng phương pháp dealloc với ARC (không gọi siêu hoặc bất kỳ mã phát hành bộ nhớ nào) - viewWillUnload không được dùng nữa trong ios 6. –

1

Tôi cũng thấy lỗi chính xác này và do đại biểu tôi đã chỉ định cho UIWebView không được giữ lại (trong trường hợp của tôi là UIViewController).

2

Tôi đã gặp sự cố EXC_BAD_ACCESS trên UIWebView cuộn, nhưng chỉ trên iPad và chỉ khi người dùng đã rời khỏi cuộn UIWebView khi đã đóng trình điều khiển chế độ xem chứa nó.

Đặt đại biểu thành nil không khắc phục được sự cố của tôi ở đây, nhưng tôi đã tìm thấy giải pháp ở nơi khác theo một vấn đề khác. Tôi đã thêm mã này vào phương thức được gọi bằng nút đóng của tôi:

for (id subview in webView.subviews){ 
     if ([[subview class] isSubclassOfClass: [UIScrollView class]]){ 
      [subview setContentOffset:CGPointZero animated:NO]; 
     } 
    } 

Điều này sẽ ngừng di chuyển trước khi phương thức dealloc được gọi, điều này có vẻ là vấn đề.

5

Xem sẽ biến mất là một lựa chọn làm việc để câu trả lời được chấp nhận:

// ARC 
- (void)viewWillDisappear:(BOOL)animated{ 
    [self.webView setDelegate:nil]; 
    [self.webView stopLoading]; 
} 

này hoạt động dành cho iOS 6 hoàn hảo.

0

Xử lý việc hủy đăng ký đại biểu khỏi chế độ xem web và dừng việc xem webview, được xử lý tốt nhất từ ​​phương thức dealloc của ViewController.

Ví dụ khi viewWillDisappear có thể thất bại: nếu ViewController là con của ViewController khác, bạn có thể kích hoạt loại bỏ khung nhìn ViewController từ khung nhìn ViewController của cha với một hoạt ảnh.Đồng thời, bạn có thể loại bỏ các ViewController từ cha mẹ của nó và không tham chiếu của nó. Tại thời điểm đó ViewController sẽ là nil và viewWillDisappear sẽ không bao giờ được gọi, nghĩa là ủy nhiệm WebView sẽ không bao giờ được dọn sạch.

Sử dụng dealloc và đảm bảo rằng WebView của bạn luôn được làm sạch.

Các vấn đề liên quan