2012-04-20 28 views
7

Tôi gặp sự cố khi tôi gặp ngoại lệ truy cập kém nhưng chỉ khi chạy thử nghiệm (gọi các phương thức tương tự trong bản dựng gỡ lỗi không gây ra sự cố khi xuất hiện). Dự án đã cho phép ARC và tôi đang chạy này trên iPad 5.1 mô phỏng sử dụng Xcode 4.3:EXC_BAD_ACCESS chỉ sử dụng ARC trong khi thử nghiệm

Dưới đây là nơi mà vấn đề cây trồng lên:

- (void)testChangeFoodNotification { 
    Player* p = [[Player alloc] init]; 
    [p addObserver:self forKeyPath:@"food" options:0 context:0]; // <-EXC_BAD_ACCESS (code=2) 
    p.food += 1; 
    STAssertTrue(_wasNotifiedOfFoodChange, nil); 
} 

Tại thời điểm khi các phương pháp addObserver: được gọi là nó doesn' t có vẻ như bất kỳ của các đối tượng liên quan nên đã được phát hành vì vậy những gì có thể gây ra ngoại lệ?

EDIT:

Xin lỗi nếu nó không phải là rõ ràng nhưng các mã trên đã được thực hiện như một phần của một trường hợp thử nghiệm (sử dụng tiêu chuẩn Xcode OCUnit). Cũng trong trường hợp nó làm rõ bất cứ điều gì ở đây là mã có liên quan từ lớp cầu thủ (có ivars và các phương pháp khác, nhưng họ không có bất kỳ kết nối đến tài sản hoặc các phương pháp đang được thử nghiệm):

// Public interface 
@interface Player : NSObject 

@property (nonatomic, assign) NSInteger food; 

@end 

// Private interface 
@interface Player() { 
    NSInteger _food; 
} 

@end 

@implementation Player 

@synthesize food = _food; 

#pragma mark - Getters/Setters 

- (void)setFood:(NSInteger)food { 
    [self willChangeValueForKey:@"food"]; 
    _food = food; 
    [self didChangeValueForKey:@"food"];  
} 

Trả lời

21

Nếu lớp học của bạn thực sự tuân thủ khóa-giá trị, hãy đảm bảo rằng việc triển khai cho lớp hiển thị vấn đề không được bao gồm trong sản phẩm thử nghiệm của bạn. Điều này có nghĩa là bảng điều khiển thành viên mục tiêu của trình kiểm tra danh tính cho tệp .m của bạn sẽ chỉ được kiểm tra ứng dụng của bạn (không phải ứng dụng của bạn).

Tôi gặp vấn đề tương tự trong Xcode 4.3.1 khi triển khai được bao gồm trong cả hai sản phẩm và tôi đã đăng ký các nhà quan sát trong cả mã sản xuất và mã kiểm tra. Các nhật ký sau đã tắt tôi:

Lớp YourClass được thực hiện trong cả hai/Người dùng/Người dùng/Thư viện/Ứng dụng/Trình quản lý iPhone/5.1/Ứng dụng/YourUser/Library/của bạn/Nhà phát triển/Xcode/DerivedData/YourApp-/Build/Sản phẩm/Debug-iphonesimulator/YourAppTests.octest/YourAppTests. Một trong hai người sẽ được sử dụng. Cái nào không xác định.

+3

Tôi ước tôi có thể upvote 100 lần này. Cảm ơn! – DexterW

+0

Tôi cũng gặp sự cố này với CocoaPods. Tệp triển khai lớp được bao gồm trong nhóm cho cả mục tiêu thử nghiệm ứng dụng và ứng dụng, ngoại trừ không có cảnh báo lớp trùng lặp trong nhật ký. – Eric

0

Theo Key-Value Observing Programming Guide, được Trình chỉnh sửa khóa-giá trị của trình phát của bạn? Bạn muốn đảm bảo rằng bạn là Ensuring KVC Compliance. Tôi cũng giả định rằng bạn cũng đã triển khai observeValueForKeyPath:ofObject:change:context: của mình? Nếu bạn nghĩ rằng bạn đã làm tất cả những điều này và nó vẫn không hoạt động, thì có lẽ bạn có thể chia sẻ mã của bạn.

Ngoài ra, điều nhỏ nhặt, nhưng tôi cho rằng đây là đoạn mã để làm nổi bật vấn đề. Tôi chỉ đề cập đến nó vì ARC sắp phát hành đối tượng p của bạn ở cuối testChangeFoodNotification của bạn và tôi đã nghĩ rằng bạn muốn loại bỏ người quan sát của mình trước tiên.

+0

Cảm ơn bạn đã trả lời. Tôi có thể thiếu một cái gì đó nhưng tôi nghĩ rằng lớp học tuân thủ KVC (thực tế là cùng một mã hoạt động bên ngoài một thử nghiệm xây dựng làm cho tôi nghĩ rằng đó là tuân thủ nhưng tôi có thể sai - đây là lần đầu tiên tôi sử dụng KVC/KVO). Để xóa người quan sát. Bình thường, nhưng tôi nghĩ rằng vì đây là một phương pháp test test và cả p và người quan sát sẽ bị phá hủy trước khi có bất kỳ cơ hội nào để sửa đổi p một lần nữa, nên tránh làm lộn xộn phương pháp thử với boilerplate. Tôi có thể sai lầm và nếu tôi muốn nghe như thế nào;) – Mattia

+0

Vâng, tôi không thấy nó. Lấy làm tiếc. Tôi không hiểu tại sao bạn định nghĩa giao diện riêng của bạn cho _food cũng như lý do tại sao bạn viết setter của riêng bạn (câu lệnh @synthesize thực hiện cả hai cho bạn), nhưng nghi ngờ đó là nguồn gốc của vấn đề. Quan trọng hơn, tôi không hiểu tại sao bạn nhận được hành vi khác nhau trong bản sửa lỗi v thử nghiệm. Tôi chỉ có thể đề nghị bạn bật zombie bằng cách sửa đổi sơ đồ của bạn trong bản dựng thử nghiệm của bạn, nếu bạn chưa có, và xem liệu nó có khai sáng hơn hay không. – Rob

+0

Ban đầu tôi đã không thêm người định cư của riêng tôi nhưng tôi đã thêm họ để xem đó có phải là vấn đề không (tôi nghĩ có lẽ những người được tổng hợp không gọi là/didChangeValueForKey - điều đó dường như không phải là trường hợp). Lý do tôi khai báo biến riêng của tôi là thói quen: Tôi thích các dấu gạch dưới của tôi với dấu gạch dưới và trình biên dịch tổng hợp chúng mà không có dấu gạch dưới. Trong mọi trường hợp, cảm ơn bạn đã xem qua. – Mattia

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