2009-06-19 7 views
7

Khi tôi cố gắng biên soạn ứng dụng của tôi cho OS 3 tôi gặp phải một lỗi sau:Thay đổi mục tiêu-C giữa OS 2.2.1 và OS 3?

lỗi: loại accessor không phù hợp với loại tài sản

Các lỗi được cho một tài sản tôi đã cố gắng để truy cập vào đó là được định nghĩa như sau:

NSMutableArray *myArray 

@property (readonly,nonatomic) NSArray* myArray; 

thuộc tính này được @synthesized trong tệp triển khai.

này chỉ làm việc tốt trong OS 2.2.1 nhưng không là OS 3.0

Viết phương pháp getter bản thân mình giải quyết vấn đề.

Có ai biết về các thay đổi đối với mục tiêu-c giữa OS 2.2.1 và 3.0 không? Có tài liệu nào cho những thay đổi này không?

API changes document dường như không chứa bất kỳ điều gì về vấn đề này.

EDIT

lỗi xảy ra khi bạn cố gắng truy cập thuộc tính, ví dụ:

NSArray *anArray = myClass.myArray; 

Như tôi đã đề cập ở trên, tôi đã tìm thấy cách giải quyết cho vấn đề này: viết phương pháp getter, tuy nhiên những gì tôi thực sự là tài liệu từ táo giải thích thay đổi này và bất kỳ thay đổi nào khác không liên quan đến API .

Nhờ sự giúp đỡ của bạn

Trả lời

17

Đây là lỗi trình biên dịch.

Mặc dù bạn không nói rõ nó hoàn toàn, tôi hy vọng mã của bạn trông như thế này:

@interface Foo : NSObject { 
    NSMutableArray *objects; 
} 
@property (readonly, copy) NSArray *objects; 
@end 

@implementation Foo 
@synthesize objects; 
@end 

Trình biên dịch được, không may, nhầm lẫn giữa việc kê khai của objectstài sản và khai báo của objectsbiến thể hiện. Hãy nhớ rằng các thuộc tính và các biến mẫu là những thứ khác nhau trong Objective-C; một thuộc tính có thể được hỗ trợ bởi một biến cá thể, nhưng nó thực sự là một phần của giao diện công khai của một lớp.

Bạn có thể làm việc này bằng cách thay đổi mã của bạn để tách rõ nét của biến dụ từ định nghĩa của tài sản, ví dụ bằng cách đặt trước tên của biến Ví dụ:

@interface Foo : NSObject { 
    NSMutableArray *_objects; 
} 
@property (readonly, copy) NSArray *objects; 
@end 

@implementation Foo 
@synthesize objects = _objects; 
@end 

Bằng cách này, trình biên dịch không bị lẫn lộn về tài sản so với biến mẫu trong các biểu thức như self.objects (mà nó không nên anyway, nhưng dường như không).

Chỉ cần bắt đầu phản hồi không thể tránh khỏi: Apple không đặt trước tiền tố thanh thiếu cho các biến mẫu. Nó được dành riêng cho các phương thức.Bất kể, nếu bạn không thích thanh dưới, hãy sử dụng tiền tố khác.

+0

Xin chào Chris. Trên thực tế tôi đã chỉ định toàn bộ mã có liên quan, hơn nữa đề xuất của bạn cho chỉ đọc, sao chép tài sản không thực hiện bất kỳ ý nghĩa và tôi nghi ngờ trình biên dịch sẽ cho phép nó đi. Tôi tiếp tục cảm nhận được rằng mọi người không thực sự đọc những câu hỏi đó là một sự xấu hổ bởi vì tôi đã vui mừng về trang web này trong khoảng ba ngày. Và bạn đã không trả lời câu hỏi của tôi đó là lý do tại sao nó được sử dụng để làm việc và không phải là bây giờ, và trỏ đến một số tài liệu từ táo về nó. –

+6

Ron, bạn chỉ cần khai báo biến không phải là khai báo ivar trong một @interface. Hơn nữa, (chỉ đọc, sao chép) sẽ hoạt động và hoàn toàn hợp lý: Nó nói rằng thuộc tính sử dụng kiểu "copy" của quản lý bộ nhớ, và trong lớp này là chỉ đọc. (Một phân lớp có thể ghi đè điều đó.) Cuối cùng, tôi nhớ rằng nó hoạt động trước iPhone OS 3.0 SDK và không hoạt động trong iPhone OS 3.0 SDK đặc biệt do lỗi trình biên dịch. Bạn có thể đọc "Ngôn ngữ lập trình 2.0 mục tiêu-C" để xem hành vi của ngôn ngữ nên là gì. –

+0

Ron, những gì bạn đăng trong câu hỏi chắc chắn không phải là mã thực tế bạn đang sử dụng, vì có lỗi cú pháp trong đó sẽ ngăn nó biên dịch (dòng đầu tiên yêu cầu dấu chấm phẩy). Những gì Chris đoán là điều duy nhất hợp lý, nếu bạn đang làm điều gì đó thực sự kỳ lạ, bạn cần phải đăng mã thực tế. –

5

chỉnh sửa: câu trả lời gốc gỡ bỏ sau khi đánh giá ngang hàng tìm thấy nó thiếu. Vui lòng đọc ý kiến ​​của Chris Hanson về vấn đề này. Tôi để phần còn lại ở đây vì tôi nghĩ nó vẫn còn hợp lệ.


Lưu ý rằng ngay cả khi bạn khai báo các loại tài sản để được NSArray, đối tượng quay trở lại vẫn là một NSMutableArray, và các phương pháp có thể thay đổi được định nghĩa cho nó. Khai báo thuộc tính theo cách này là không phải là ngăn người khác vô tình đột biến mảng.

Nếu bạn muốn chắc chắn rằng mảng được trả về là không thể thay đổi, bạn có thể kê khai tài sản như trong ví dụ ban đầu của bạn, và sau đó cuộn accessor của riêng bạn:

- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; } 

Lưu ý rằng điều này sẽ trả về một unretained NSArray. Nó sẽ được cho người gọi để có quyền sở hữu của đối tượng nếu nó cần thiết để tồn tại.

+0

Như tôi đã đề cập, tôi đã tự viết phương thức getter và nó đã thực hiện thủ thuật. Cảm ơn –

+0

Vâng, tôi khá chắc chắn rằng làm cho câu trả lời này, Ron. –

+0

Trên thực tế nó không phải là một câu trả lời nó là một workaround, và như tôi đã đề cập trong câu hỏi tôi đã tìm thấy một workaround. Những gì tôi đang tìm kiếm là một giải thích tại sao điều này làm việc trong 2.2.1 và không còn nữa và tốt hơn là nơi mà tài liệu này được ghi lại. –

4

Bạn đang nhìn thấy sai lầm vì XCode hiện đang đưa ra cảnh báo và các lỗi cho những thứ đó trước đây chưa hề ...

tôi cho rằng nó nên có ít nhất một cảnh báo để làm những gì bạn đang làm, tôi hiểu bạn cố gắng trình bày các mảng như bất biến với thế giới bên ngoài nhưng có thể biến đổi bên trong lớp. Bạn có thể muốn xem xét một accessor khác với một tên khác, được xây dựng để trả về mảng có thể thay đổi cụ thể.

0

Vì vậy, điều này thực sự liên quan đến cuộc gọi @synthesize không vui khi tiết lộ NSMutableArray như một NSArray - tại sao không chỉ triển khai getMethod.

Thực sự nghĩ về nó, nó phải là phương pháp thiết lập không vui - bạn sẽ không thể đặt NSArray thành NSMutableArray.

+0

Trong khi sự cố có thể phát sinh từ @synthesize, liệt kê nhanh gọi getter, chứ không phải setter, do đó lỗi vẫn có vẻ hơi lệch. –

+0

hơn nữa tài sản được đánh dấu là chỉ đọc vì vậy thực sự không có phương pháp setter nào cả. –

+0

vâng tôi đã quên điều đó - do đó, vấn đề chỉ là với giềng @synthesized – Grouchal

1

Nó vẫn là Mục tiêu-C 2.0; trình biên dịch chỉ là một chút cập nhật với việc xem xét loại kiểu này thay đổi một lỗi. Nó khá nhiều nên là một lỗi. Ít nhất nó nên cảnh báo bạn rằng bạn có thể không có nghĩa là những gì bạn đã viết. Sau đó, bạn có thể truyền nội dung để làm cho nó không cảnh báo bạn, điều bạn không thể làm với tuyên bố @synthesize.

Tôi chỉ dán chính xác mã của bạn và một câu lệnh tổng hợp vào bộ điều khiển của tôi và tôi không có lỗi hoặc cảnh báo về nó. Nó được xây dựng tốt. Bây giờ tôi đặt SDK cơ sở thành "Mô phỏng 3.0" và bản dựng thành "Trình gỡ lỗi mô phỏng 3.0". Dự án này đã bắt đầu trong SDK 2.2.1 và tôi vừa cài đặt SDK 3.0 ngày hôm qua; Xcode là phiên bản 3.1.3.

Cập nhật: Ồ tôi thấy rằng thực sự cố gắng đặt thuộc tính là nơi bạn nhận được lỗi mà bạn đã đề cập.

self.myArray = [NSArray arrayWithObject:@"foo"]; 

Rõ ràng bạn không thể @synthesize hành vi này và phải viết người truy cập của riêng bạn.

- (NSArray*)myArray { 
    return [NSArray arrayWithArray:myArray]; 
} 
- (void)setMyArray:(NSArray*) pMyArray { 
    myArray = [NSMutableArray arrayWithArray:pMyArray]; 
} 

Điền trong những accessors, đã không làm cho thông điệp đi xa, vì vậy tôi đã phải thay đổi các quyền truy cập vào:

[self setMyArray:[NSArray arrayWithObject:@"foo"]]; 

Sử dụng cú pháp trên mà không accessors tùy chỉnh cũng không làm việc.

PS Ồ, có ai khác khó chịu rằng bạn không thể sao chép bong bóng tin nhắn hoặc văn bản trong cửa sổ kết quả xây dựng không?

+1

Tôi thực sự khó chịu về việc không thể sao chép tin nhắn hoặc văn bản. Nếu bất cứ ai có thể tìm ra giải pháp cho điều đó, điều đó sẽ rất tuyệt. Trong mọi trường hợp như tôi đã nói tài sản trong trường hợp của tôi là chỉ đọc vì vậy không có vấn đề trong đại diện cho nó như là NSArray, và khi tôi viết phương thức getter của riêng nó nó hoạt động không có lỗi. –

+2

Thanh trượt ngang (ở cuối phần trên cùng) của cửa sổ kết quả xây dựng có biểu tượng với các dòng văn bản (bên cạnh dấu kiểm và dấu hiệu cảnh báo). Nếu bạn nhấp vào nó, bạn sẽ nhận được nhật ký thô, có thể sao chép được. – Kornel

+0

@pormeL cảm ơn mẹo. Rất hữu ích –

0

câu hỏi của bạn là:

Is anyone aware of changes to objective-c between OS 2.2.1 and 3.0?

Is there any documentation for these changes?

Những câu trả lời dứt khoát là:

1) Không có thay đổi có chủ ý để đặc tả ngôn ngữ, nhưng trình biên dịch và các công cụ phát triển khác thay đổi. Chris và các đồng nghiệp của anh là những chuyên gia về những thay đổi đó.

2) Có lẽ không, bởi vì bất kỳ thay đổi nào không chủ ý hoặc được thực hiện để phù hợp hơn với hành vi của tài liệu.

Bạn không nên nhanh chóng loại bỏ câu trả lời của Chris là "phỏng đoán". Chris làm việc trên các công cụ phát triển của Apple. Bạn có thể nhận được câu trả lời khác mà bạn thích hơn, nhưng bạn sẽ không nhận được câu trả lời chuyên môn hơn.

+0

Cảm ơn pbm. Lưu ý và tôi chấp nhận câu trả lời của Chris –