2010-09-10 36 views
36

Tôi có ứng dụng SDK dành cho iPhone có một số chế độ xem xuất hiện và biến mất khi người dùng tạo nội dung. Sau khi sử dụng ứng dụng trên thiết bị trong một thời gian, tôi nhận được sự cố sau:Lỗi UIScrollView EXC_BAD_ACCESS trong SDK iOS

Program received signal: “EXC_BAD_ACCESS”. 
(gdb) backtrace 
#0 0x33369ebc in objc_msgSend() 
#1 0x320e5248 in -[UIScrollView(UIScrollViewInternal) _scrollViewAnimationEnded]() 
#2 0x338b4a14 in -[NSObject performSelector:withObject:]() 
#3 0x320e5098 in -[UIAnimator stopAnimation:]() 
#4 0x320e4b7c in -[UIAnimator(Static) _advance:]() 
#5 0x320e4a34 in LCDHeartbeatCallback() 
#6 0x34350e60 in HeartbeatVBLCallback() 
#7 0x332e91c0 in IOMobileFramebufferNotifyFunc() 
#8 0x316532f8 in ??() 
#9 0x33866b50 in __CFMachPortPerform() 
#10 0x338ae52a in CFRunLoopRunSpecific() 
#11 0x338adc1e in CFRunLoopRunInMode() 
#12 0x3434e1c8 in GSEventRunModal() 
#13 0x32002c30 in -[UIApplication _run]() 
#14 0x320in UIApplicationMain() 
#15 0x00002ff8 in main (argc=1, argv=0x2ffff550) at /Developer/svn/MyCompany/iPhone/MyApplication/Other Sources/main.m:14 

Như bạn có thể thấy từ theo dõi, chỉ đề cập đến mã của tôi trong đó là lời gọi đến chính.

Tôi đã chạy Build and Analyze từ Xcode, và cũng có thể thiết lập để chạy trình phân tích clang trên dự án của tôi từ Terminal, và cả hai không thể tìm thấy bất kỳ vấn đề nào trong mã. Tôi đang sử dụng phiên bản phát hành rất gần đây của SDK iOS (Tôi chưa tải xuống phiên bản 4.1, nhưng phiên bản tôi đang sử dụng là phiên bản đã được phát hành ngay trước 4.1).

Ngoài ra, tôi đã chạy ứng dụng trong Dụng cụ có Trình mô phỏng và ứng dụng không bị rò rỉ bộ nhớ.

Tôi sắp thử sử dụng biến số NSZombieEnabled và xem có tìm thấy gì không, nhưng vấn đề là tôi cần sử dụng ứng dụng từ 30 đến 40 phút hoặc lâu hơn trước khi nó bị treo và tôi nghi ngờ rằng NSZombieEnabled có thể không thậm chí giúp tôi tìm ra vấn đề.

Dường như các sự cố mà tôi đã thấy là khi chế độ xem phương thức gọi một đại biểu trong bộ điều khiển chế độ xem gốc. Trình điều khiển chế độ xem gốc sau đó thực hiện một số xử lý trước khi loại bỏ trình điều khiển chế độ xem phương thức. Có một số tài liệu tham khảo trong vụ tai nạn để xem hoạt hình và cuộn, nhưng tôi không chắc chắn những gì tôi có thể làm để làm cho những người có vấn đề. Có ai có bất cứ đề nghị cho những thứ để tìm?

EDIT: Tôi đã đặt NSZombieEnabled cờ vào ứng dụng, và trên thiết bị, nó đi kèm với thông báo này trong giao diện điều khiển:

2010-09-11 17:10:33.970 MyApplication[9321:207] *** 
-[MyViewController respondsToSelector:]: message 
sent to deallocated instance 0x7489480 

Theo như tôi có thể nói, tôi đang thiết các đại biểu được sử dụng trong ứng dụng để nil trong deallocs của tất cả các lớp học của tôi, vì vậy tôi bị mắc kẹt như là nơi để xem xét tiếp theo.

Tôi đã cố gắng sử dụng lệnh địa chỉ malloc_history pid về điều này, nhưng nó nói rằng nó không thể tìm thấy quá trình, tôi đã thử 9321, 9321: 207 và 207. Ngoài ra, nếu tôi cố gắng sử dụng biến số MallocStackLogging, chương trình sẽ không chạy trên thiết bị, tôi nhận được một bó số malloc: không thể tạo thư mục ngăn xếp nhật ký ngăn xếp trong bảng điều khiển và sự cố chương trình. Ồ, và bằng cách này, tôi không thể sử dụng zombie kiểm tra trong Dụng cụ, vì nó dường như không hoạt động với một thiết bị, và tôi không thể xảy ra sự cố tương tự xảy ra trong Trình mô phỏng.

Trả lời

42

UIScrollView trên ngăn xếp khung # 1 có thể muốn thông báo cho đại biểu của mình về hoạt ảnh kết thúc, nhưng đại biểu đã đi vào thời điểm đó. Thiết lập NSZombieEnabled có thể sẽ xác nhận điều này.

Đại biểu không được giữ lại, vì vậy đây là lỗi thường gặp trong Cocoa và Cocoa Touch. Tìm kiếm đại biểu trên UIScrollView hoặc UITableView trong mã của bạn và cố gắng tìm hiểu xem ai có thể được phát hành trước thời gian của họ.

+0

+1. Để rõ ràng, các thuộc tính ủy nhiệm phải luôn được đặt thành 'chỉ định' và không phải' giữ lại ' –

+0

Luôn có một ngoại lệ đối với quy tắc. Xem 'NSURLConnection' để biết lý do hợp lệ để giữ lại một đại biểu. –

+0

Tôi có một UITableView nằm trên một UIViewController, và khi ứng dụng bị treo, tôi tin rằng nó đã sẵn sàng để quay trở lại bộ điều khiển xem này. Tuy nhiên, đại biểu cho UITableView này được thiết lập trong Interface Builder, và nó không được thay đổi bất cứ nơi nào trong mã. –

3

Dự đoán của tôi là đại biểu của scrollview được đặt thành đối tượng đã được deallocated. Hãy thử cài đặt tất cả các đại biểu của các đối tượng con thành nil trong các phương thức dealloc của bạn.

61

Tôi vừa tự mình khắc phục sự cố này.

Tôi đã có một vấn đề mà:

  • Một đại biểu scrollview được nối với một UIViewController
  • Các scrollview bắt đầu hiệu ứng động
  • Các đại biểu đã đi xa và dealloc được gọi.

Sự cố là thư ủy quyền scrollview được kích hoạt trên đối tượng được phân phối mới và nhật ký sự cố hơi khó hiểu khi chúng trỏ đến các tham chiếu đối tượng vô nghĩa.

Khắc phục là đặt đại biểu scrollview thành nil làm dòng đầu tiên trong phương thức dealloc của trình điều khiển chế độ xem của tôi.

Hy vọng điều này sẽ giúp người khác!

+5

Bạn có thể không biết bạn gặp khó khăn như thế nào khi bạn đã cứu tôi với câu trả lời này, cảm ơn bạn: D – rastating

+0

Thanx cho câu trả lời này! Đã lưu tôi rất nhiều thời gian – derpoliuk

+0

Tôi đã theo dõi câu trả lời của chip trước đó nhưng điều này có ý nghĩa hơn đối với tôi và giúp tôi giữ mã của tôi sạch sẽ. Cảm ơn. +1 – Avi

16

Để hoàn thành, tôi thêm dấu vết ngăn xếp này (iOS 6) cho những người có thể gặp phải vấn đề tương tự nhưng với một chút triển khai khác và các bước chính xác để tái tạo sự cố.

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x71f05631 
Crashed Thread: 0 

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3919b5d0 objc_msgSend + 1 
1 UIKit       0x33421830 -[UIScrollView(UIScrollViewInternal) _delegateScrollViewAnimationEnded] + 48 
2 UIKit       0x334217ba -[UIScrollView(UIScrollViewInternal) _scrollViewAnimationEnded:finished:] + 130 
3 UIKit       0x334216a4 -[UIAnimator stopAnimation:] + 460 

này đang xảy ra trên iOS 6 và bắt đầu xảy ra khi tôi thực hiện phương pháp UIScrollViewDelegate:

" -(void)scrollViewDidEndDecelerating:(UITableView *)tableView" 
and made a call to: 
"[tableView scrollToRowAtIndexPath: indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];". 

Vấn đề xảy ra khi các hình ảnh động bắt đầu và tôi nhấn nút "Back" và quan điểm của tôi bộ điều khiển được bật ra trước khi hoạt ảnh hoàn tất.

Khi sao chép, bạn phải chắc chắn nhấn nút "Quay lại" sau khi hoạt ảnh bắt đầu nhưng trước khi quá trình này hoàn tất. Tôi đã thử một vài lần. Tôi đã cố gắng để tái tạo vấn đề bằng cách lập trình popping bộ điều khiển xem ra nhưng không thể tái tạo nó. Tôi đã phải sử dụng nút "Back". Tôi đã gọi đơn giản là [phát hành myTableView] trong dealloc. Các giải pháp được như mô tả ở đây để thiết lập cả hai thuộc tính để nil:

self.myTableView.delegate = nil; 
self.myTableView = nil; 
+0

cảm ơn bạn đời. nó đã khiến tôi phát điên ... –

+0

Cảm ơn, tôi không thể giải quyết sự cố này trong cả ngày .. – Nikita

2

Điều này có thể xảy ra nếu bạn chèn một bộ điều khiển làm tươi vào một cái nhìn bảng như là một subview (gợi ý của tôi, không bao giờ làm điều đó) ...

+0

Bạn có bằng chứng nào không? Thực hiện thay đổi, nhưng tôi không chắc chắn liệu nó có khắc phục được sự cố không. – mOp

+0

từ kinh nghiệm của riêng tôi (và chính xác cùng một vấn đề), như một số phần của API cũ sử dụng gán (thay vì yếu mới, và để treo lên với con trỏ chết) - đây là trường hợp chắc chắn nếu bạn chèn UIRefreshController như một Subview (KHÔNG BAO GIỜ LÀM R !NG! UIRefreshController không có nghĩa là để được chèn vào như subview) –

+0

Tôi đi qua cùng một lỗi và nghi ngờ rằng vấn đề đã được chèn một UIRefreshController như là một subview của một đối tượng UITableView. Mỗi tài liệu của Apple, UIRefreshControl chỉ nên được sử dụng với một UITableViewController nhưng tôi đã được giao dịch với một UIViewController di sản. Sau khi gỡ lỗi thêm, tôi đã phát hiện ra rằng vấn đề là ứng dụng đã mất một tham chiếu một đối tượng được tạo ra trong một trong các phương thức UITableViewDelegate của tôi trong UIViewController. Tất cả tôi cần làm là tạo ra một tài sản trong UIViewController và đặt nó vào đối tượng đó. – Vee

7

Lúc đầu, đại biểu phải là yếu/chỉ định loại. Nhưng sự kiện trong trường hợp này có một trở ngại rất phổ biến được điều khiển bởi hoạt ảnh cuộn. Nếu bạn sử dụng nội dung hoạt hình bù đắp những thay đổi cho ScrollViews bạn bạn mạnh mẽ, cần phải thiết lập đại biểu của nó-nil tại dealloc phương pháp.

Nếu không, bạn sẽ nhận được

sau
[YourViewController respondsToSelector:]: message sent to deallocated instance 

Ví dụ rất phổ biến:

1. _tableView is ivar of YourViewController 
2. _tableView.delegate = self; 
3. - (void)scrollViewDidScroll:(UIScrollView *)scrollView is implemented at YourViewController 
4. at some point you call [_tableView scrollToRowAtIndexPath:indexPath 
    atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
    or [_tableView setContentOffset:CGPoint animated:YES] 
    and try to close YourViewController 

Các _tableView được giữ lại bởi CoreAnimation, nhưng YourViewController được deallocated!

+1

Tôi có một vấn đề simililar, tôi nghĩ rằng ... của nó trong scrollView didScroll delegate phương pháp. Nhưng một dự án ARC của nó bây giờ vậy làm thế nào điều đó có thể xảy ra? – logixologist

+3

+1 cho '_tableView' được giữ lại bởi CoreAnimation – fatuhoku

2

Tất cả những điều trên không khắc phục được sự cố của tôi, vì vậy tôi lại đào sâu mã của mình. Tôi nhận ra rằng sự cố xuất hiện khi tôi thực hiện bàn phím và Hình động UICollectionView (vâng, đó là trò chuyện) và loại bỏ bộ điều khiển hiện tại.

Lỗi ứng dụng vì tôi cố gắng cuộn trong khối hoàn thành hoạt ảnh :)

Chỉ cần cắt và tất cả hoạt động tốt ngay bây giờ!

Chúc mừng mã hóa và gỡ lỗi :)

1

Sau khi phải đối mặt với cùng một vấn đề tôi đặt:

self.collectionView.delegate = nil; 

trong - (void)viewDidLoad (trước khi thực sự thiết lập ViewController như collectionView đại biểu) và -(void)viewWillDisappear:(BOOL)animated

Tất cả mọi thứ hoạt động tốt hiện nay.

Cảm ơn bạn đã trợ giúp.

0

Tôi đã nhìn thấy hành vi như vậy, khi gọi scrollToRowAtIndexPath không có chỉ mục hiện tạiPath

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