2009-10-26 1 views
13

Tôi là một nhà phát triển .NET kỳ cựu, bước đột phá đầu tiên của tôi vào lập trình C Mục tiêu. Tôi gặp khó khăn với một tài sản của một loại enum. Một số bối cảnh ... Tôi có một tiêu đề lớp và enum như thế này:Sử dụng các loại enum như các thuộc tính trong Mục tiêu C

typedef enum { 
    Open, 
    Unavailable, 
    Unknown 
} LocationStatus; 

@interface Location : NSObject { 

    LocationStatus status; 
} 

@property (nonatomic) LocationStatus status; 

@end 

và thực hiện điều đó trông như thế này:

@implementation Location 

@synthesize status; 

@end 

Tại một số điểm trong các mã, tôi đang thiết lập các giá trị như thế này:

location1.status = Open; 

các debugger sau đó đánh giá này là có giá trị đúng, và nó được giải quyết để enum đúng (lưu ý cũng có những tài sản khác không được hiển thị ở đây ... họ cũng đánh giá đúng).

Sau đó trong mã này, tôi cố gắng để đọc rằng bất động sản như thế này:

LocationStatus status = location.status; 

Tại thời điểm này trong các mã, trình gỡ lỗi có thể đánh giá tất cả các thuộc tính của lớp học của tôi một cách chính xác, ngoại trừ Status, hiển thị địa chỉ bộ nhớ, nhưng không hiển thị giá trị thực. Khi việc thực hiện đạt đến dòng này, tôi liên tục nhận được lỗi EXC_BAD_ACCESS trong bảng điều khiển và ứng dụng gặp sự cố.

Tôi khá chắc chắn điều này phản ánh một sự hiểu lầm cơ bản về phần của tôi về cách sử dụng tài sản và enums trong Mục tiêu C (và có thể là C nói chung). Nếu ai đó có thể làm sáng tỏ điều này, tôi sẽ biết ơn nhất.

Trả lời

5

EXC_BAD_ACCESS hầu như luôn có nghĩa là bạn đang cố gắng sử dụng tham chiếu đến đối tượng đã được phân bổ lại (thường là lỗi quá phát hành). Tìm kiếm lỗi đó ở đây trên SO để tìm số lời khuyên về việc theo dõi nó xuống.

+0

Đó là suy nghĩ đầu tiên của tôi ... rằng tôi đã phát hành giá trị ở đâu đó. Điều gây nhầm lẫn cho tôi là tìm kiếm mã cho thấy chỉ có một vị trí trong toàn bộ codebase rằng thuộc tính này nhận giá trị được gán cho nó và đặt điểm ngắt có chứng minh rằng nhiệm vụ này chỉ xảy ra một lần.Ngoài ra, bởi vì LocationStatus là một enum, tôi không phải phân bổ nó, có nghĩa là tôi không thể chỉ định nó được phát hành như thế nào (tôi hoàn toàn mở để được sai ở đây, nhớ bạn). Vì vậy, làm thế nào nó có thể đã được phát hành sớm và làm thế nào tôi có thể ngăn chặn nó? Có cách nào tốt hơn để gán các giá trị enum? –

+0

Suy nghĩ đầu tiên của tôi là điều đã hết hạn là nội dung của biến vị trí của bạn trong nhiệm vụ đó. Nhưng bật zombie, và bạn có thể thấy chắc chắn! –

7

Có thể đã quá muộn để trả lời câu hỏi này nhưng tôi đã chú ý một điều trong mã của bạn. Bạn đang sử dụng 2 biến khác nhau trong mã vị trí1 và vị trí (không có 1).

EXEC_BAD_ACCESS thường có nghĩa là bạn đang cố gắng gửi thư đến một đối tượng không tồn tại. Thông thường điều này là bởi vì nó đã được deallocated. Tuy nhiên, trong trường hợp của bạn có vẻ như nó chưa bao giờ tồn tại ở nơi đầu tiên.

Như bạn đã lưu ý, bạn không phân bổ một enum. Nhưng nó không phải là enum đó là vấn đề. Cú pháp "dấu chấm" trong mục tiêu-c chỉ là một đoạn cắt ngắn để gửi một thông điệp truy cập.

Mã của bạn là tương đương với:

LocationStatus status = [location status]; 

Đó gửi tổng hợp -(LocationStatus)status{} điệp tới đối tượng vị trí không tồn tại (tất nhiên trừ location1 chỉ là một lỗi đánh máy trong bài viết của bạn, nhưng không phải trong mã của bạn, mà làm cho bình luận của tôi không liên quan). Vì vậy, chỉ cần thay đổi location.status thành location1.status và bạn nên sẵn sàng sử dụng (trừ khi, tất nhiên, location1 đang được phát hành trước khi bạn gửi thư đến đó).