17

Chúng tôi tiếp tục gặp sự cố ngẫu nhiên, kỳ lạ với NSDateFormatter. Dấu vết ngăn xếp có liên quan là:NSDateFormatter bị treo khi được sử dụng từ các chủ đề khác nhau

Program received signal: “EXC_BAD_ACCESS”. 
#0 0x00000005 in ??() 
#1 0x0213e3c3 in udat_parse() 
#2 0x01d4e1ca in CFDateFormatterGetAbsoluteTimeFromString() 
#3 0x01d4e225 in CFDateFormatterCreateDateFromString() 
#4 0x003e2608 in getObjectValue() 
#5 0x003e2921 in -[NSDateFormatter getObjectValue:forString:errorDescription:]() 
#6 0x003e21cd in -[NSDateFormatter dateFromString:]() 

Trình định dạng ngày vẫn còn trong bộ nhớ (tức là không được phát hành hoặc bị hỏng). Điều duy nhất tôi có thể nghĩ là các chuỗi khi sụp đổ không phù hợp với định dạng, nhưng tôi nghi ngờ rằng sẽ làm cho trình định dạng hoàn toàn sụp đổ. (nó không tầm thường để kiểm tra định dạng trước).

Mọi suy nghĩ?

Trả lời

43

Nhờ người trả lời trước.

Đây không phải là vấn đề về bộ nhớ. Nó hóa ra là một vấn đề đồng bộ hóa. NSDateFormatter s không phải là chủ đề an toàn; đã có một chủ đề nền cố gắng sử dụng cùng một trình định dạng cùng một lúc (do đó tính ngẫu nhiên).

Hy vọng điều này sẽ giúp ai đó trong tương lai!

+0

cảm ơn đã giúp tôi: D cùng một vấn đề và nó chỉ xảy ra ngẫu nhiên, cảm ơn rất nhiều. –

+1

vậy bạn đã khắc phục nó như thế nào? – user102008

+3

Tôi đảm bảo rằng mỗi luồng truy cập NSDataFormatter của riêng nó. Nếu bạn không lo lắng về tranh chấp, bạn có thể chỉ cần thêm '@synchronized (dateFormatter) {...}' xung quanh mã sử dụng nó. – jbenet

1

EXCBADACCESS sẽ xảy ra khi bạn sử dụng bất kỳ đối tượng deallocated ... Cố gắng sử dụng NSZombie .. Đó là một cách dễ dàng để tìm nơi EXCBADACCESS xảy ra ... Nó sẽ xác định những phương pháp ở đâu và đó đối tượng được deallocated

Xem liên kết này http://www.markj.net/iphone-memory-debug-nszombie/

+1

EXC_BAD_ACCESS không chỉ xuất hiện trên các đối tượng được phân phối. Nó có nghĩa là bất kỳ truy cập bộ nhớ xấu (như một segfault!). Chắc chắn, trong hầu hết các trường hợp, vấn đề bộ nhớ iphone là quá phát hành, nhưng trong trường hợp này nó bật ra được một vấn đề đồng bộ: con trỏ đã được sửa đổi bởi các chủ đề khác nhau dẫn đến một con trỏ dictferencing không có thật. – jbenet

+0

cảm ơn vì đã cố gắng giúp đỡ :) – jbenet

1

Đặt cược của tôi là chuỗi bạn chuyển vào trình định dạng ngày được phát hành quá mức.

+0

Tôi đã kiểm tra điều này rất nhiều lần. Cả trình định dạng và chuỗi không được phát hành quá mức. Hóa ra là một vấn đề đồng bộ! – jbenet

3

Một giải pháp khác là tuần tự hóa việc thực thi mã sử dụng NSDateFormatter s hoặc bất kỳ đối tượng không an toàn nào khác. Sử dụng Grand Central Dispatch bạn có thể đẩy các mã trên main_queue:

dispatch_async(dispatch_get_main_queue(), ^(void){ 
    [some_object some_message]; 
}); 

hoặc sử dụng một hàng đợi riêng để đạt được hiệu quả tương tự:

dispatch_queue_t dispatch_queue = dispatch_queue_create("com.MyApp.serializer",NULL); 
dispatch_async(dispatch_queue, ^(void){ 
    [some_object some_message]; 
}); 
+0

Sau khi thử nghiệm hiệu suất, giải pháp này hóa ra là nhanh gấp đôi trong việc thực hiện (đơn giản) của tôi khi sử dụng bộ nhớ cục bộ. Kiểm tra hiệu suất gọi 'stringFromDate:' từ nhiều luồng. – Berik

1

tôi đã trải qua tai nạn kỳ lạ với _sigtramp mà gây ra cho ứng dụng xuất hiện bị khóa nhưng vẫn còn trên màn hình - hoàn toàn cản trở nguyên nhân gốc thực sự.

Thực tế là chúng tôi đã giới thiệu phân tích cú pháp dữ liệu đa luồng, va chạm với luồng GUI chính đang cố phân tích ngày bằng cách sử dụng NSDateFormatter.

Đặt một số đồng bộ hóa xung quanh định dạng NSDateFormatterDate calls đã giải quyết được sự cố.