2010-06-11 32 views
41

Tôi đã thấy điều này xảy ra bất cứ khi nào tôi xoay màn hình có UITableView trên đó. Tôi đã phát hiện ra rằng nó xảy ra giữa các cuộc gọi phương thức willRotatedidRotate trong UIViewController Đồng nghiệp của tôi cũng đã nhìn thấy nó ở các vị trí khác, thường là xoay vòng. Nó đã không bắt đầu xảy ra cho đến gần đây, và chúng tôi đang stumped như thế nào chúng ta nên đối phó với nó (tìm kiếm google không bật thông báo lỗi ở dạng chính xác của nó). Có ai khác gặp phải điều này mà biết phải làm gì với nó không?Điều gì gây ra lỗi này? "Vị trí CALayer chứa NaN: [240 nan]"

Trả lời

24

Tôi đã tìm thấy sự cố.

Khi bạn đặt lại khung của tableview, nó gọi phương thức ủy nhiệm tableView:heightForRowAtIndexPath: cho mỗi hàng trong bảng để có thể tính toán lại kích thước nội dung của nó nếu cần. Tại thời điểm đó, chúng tôi thực hiện một số xử lý đặc biệt để trả về chiều cao và do một số giả định xấu trong mã của chúng tôi, chúng tôi nhầm lẫn trả về NaN do sai số chia cho 0 (biến chúng tôi chia cho giả định không bao giờ bằng 0). Đảm bảo rằng chúng tôi không chia cho số không ở đây cố định nó.

+0

Tôi nhận được lỗi tương tự (cả hai vị trí & vọt chứa NaN, thông điệp thường đi theo cặp.) Chỉ ngay trước khi chế độ xem của tôi hiển thị. Không xoay, không có bảng, không tính toán ưa thích. Chế độ xem màu xám tối đơn giản có nhãn "Đang xử lý ..." và progressIndicator. Bất kỳ ai khác có ý tưởng về vấn đề này? – Olie

+1

đặt một số điểm ngắt trong phương thức viewdidload/viewwillappear của bạn và đảm bảo rằng bạn không phân chia bằng 0 ở bất kỳ nơi nào vô tình. – Kevlar

+0

Nó có thể hoặc có thể không có liên quan nhưng tôi đã nhìn thấy vụ tai nạn này nhiều hơn một cách nhất quán trong Mavericks OSX 10.9, tuy nhiên đã không nhìn thấy một lần nữa sau khi cập nhật OSX 10.9.2. –

35

(Quyết định đưa ra này bình luận và đặt nó như là một câu trả lời, vì tôi nghĩ đó là một câu trả lời tốt darned :)

Hà! Tôi cũng đã tính toán NaN (div0). Hỗ trợ gỡ lỗi chính: thông điệp được đề cập là đầu ra của NSLog(), vì vậy hãy đặt điểm ngắt trên NSLog() và xem những gì hệ điều hành đang làm tại thời điểm đó. Đối với tôi, đó là myUISlider.value = NaN.

Để đặt breakpoint:

XCode 3.x

  • CMD-SHIFT-Y (cửa sổ gỡ lỗi.)
  • nút Breakpoints.
  • "Double-click cho biểu tượng"
  • Gõ "NSLog" (không có dấu ngoặc kép.)

XCode 4.x

  • CMD-6 (breakpoint navigator.)
  • "+" để thêm điểm ngắt (phía dưới bên trái.)
  • Chọn ADD SYMBOLIC BREAKPOINT.
  • Ký hiệu: NSLog
  • Xác nhận: Xong.

XCode 5.x - 7.1 (ít nhất) (Tương tự như 4.x, trừ breakpoint navigator là CMD-7, bây giờ.)

Chạy ứng dụng, xem nó phá vỡ trên NSLog, kiểm tra dấu vết ngăn xếp.

+1

Đây là câu trả lời thực sự quan trọng khi nói đến ngoại lệ này. Điều quan trọng cần lưu ý là ngoại lệ này có thể được nâng lên từ các thành phần sử dụng CALayer và người dùng API không biết về sự tồn tại của chúng (nhờ đóng gói). – Pacu

+0

Làm thế nào 'bout 5.1 - 6.0? – Morkrom

+0

Morkrom, bạn đang nghĩ đến phiên bản iOS. Tôi đang nói về phiên bản XCode. Tôi đã không có cơ hội để kiểm tra XCode 5.x, nhưng tôi đặt cược nó không phải là quá khó để tìm ra. – Olie

12

Tôi có vấn đề này khi tôi đã giả định rằng:

tableView:heightForHeaderInSection: trả lại một NSInteger, nhưng nó sẽ trả về CGFloat ...

thay đổi:

-(NSInteger)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 

để

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 

cố định vấn đề của tôi.

Edit:

Tại một số điểm tôi đã tìm ra cách các máy tính làm việc dưới mức C, vì vậy tôi nghĩ tôi sẽ chia sẻ nó ... (Tôi sẽ sử dụng một tên đăng ký từ x86_64 như tôi quen thuộc nhất với họ , ARM sẽ hơi khác nhau nhưng tương tự)

int f(){ 
      float someFloat=5.0f; 
      return someFloat; 
     } 

kết quả trong chuyển đổi các giá trị của someFloat để một kiểu số nguyên sau đó sao chép đến một thanh ghi đặc biệt: %rax sau đó gọi các hướng dẫn trở lại.

float f(){ 
      float someFloat=5.0f; 
      return someFloat; 
     } 

kết quả trong việc sao chép giá trị của someFloat từ vị trí hiện tại của mình cho một thanh ghi đặc biệt: %xmm0 sau đó gọi các hướng dẫn trở lại.

Vì vậy, nếu bạn có mẫu thử sai mã gọi sẽ mong đợi giá trị ở sai địa điểm, bạn sẽ kết thúc thực sự trả về giá trị rác.

13

Tôi đã dành một ngày cố gắng tìm mã gây ra cùng một sự cố và giải quyết nó trong vòng một phút sau khi bật "ngắt ngoại lệ" trong Xcode. Kiểm tra this tutorial để xem cách bật tính năng này.

+1

Bạn có thể bao gồm một bản tóm tắt ngắn về nội dung của trang không? Điều này là để người đọc trong tương lai của bài đăng này có thể nhận được thông tin họ đang tìm kiếm một cách nhanh chóng và dễ dàng. – gobernador

+2

@gobernador Tôi sẽ vì nó chỉ giúp tôi! Để tìm dòng chính xác nơi ứng dụng của bạn đã chết, hãy chuyển đến tab điểm ngắt ở bên trái của xcode, nhấp +, thêm 'Điểm ngắt ngoại lệ' mới và để cài đặt mặc định. Nhấp vào Xong và chạy lại ứng dụng của bạn. – spamoom

2

Lỗi này cũng khiến tôi mất nhiều thời gian.
Vào cuối tôi thấy đồng nghiệp của tôi đã viết một cái gì đó như thế này:

UIEdgeInsets a; 
a.left = (...some calculation); 
button.imageEdgeInsets = a; 

Và tôi viết lại những mã như thế này và khắc phục vấn đề:

UIEdgeInsets a; 
a.left = (...some calculation); 
a.top = 0; 
a.bottom = 0; 
a.right = 0; 
button.imageEdgeInsets = a; 

một số giá trị của UIEdgeInsets không được khởi tạo đúng, và đôi khi nó trở thành giá trị NaN và làm hỏng ứng dụng.
Nói chung, bạn nên kiểm tra xem tất cả các giá trị của cấu trúc kiểu C được khởi tạo đúng cách.

0

Có một cách khác để tạo lại vấn đề: sử dụng insetBy(dx:dy:) trên rect quá nhỏ

enter image description here