2015-06-14 20 views
7

Vì vậy, rõ ràng, sau WWDC tôi đang chơi với những thứ mới được trình bày trong tuần trước. Như bạn đã biết Apple giới thiệu Generics với thế giới của Objective-Cgenerive-C generics không làm việc cho các phương pháp? (Xcode 7 Beta (xây dựng: 7A120f))

Lưu ý: Câu trả lời này là bằng cách nào đó theo dõi cho câu hỏi này: Are there strongly-typed collections in Objective-C?

Tôi đã thử mã này trong phương pháp, hoạt động tuyệt vời

NSMutableArray<NSString*> *array = [[NSMutableArray alloc] init]; 

[array addObject:@""]; 
[array addObject:@(54)];Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString * __nonnull' 
// Great, generics works as expected. 

Tuy nhiên tôi cũng có phương pháp tôi muốn chuyển đổi để Generics

Trong tập tin tiêu đề:

- (NSArray <NSString*> *)objectsToSearch; 

Thực hiện:

- (NSArray <NSString*> *)objectsToSearch 
{ 
    NSString *first = @"1"; 

    NSString *second = @"2"; 

    NSString *third = @"3"; 

    NSNumber *test = @(55); 

    return @[first, second, third, test]; // No-error!!! 
} 

Am tôi làm điều gì đó sai hoặc Clang không hỗ trợ Generics + literals hoặc có cái gì đó khác tôi đang thiếu?

+0

Có bạn đang làm điều gì đó sai, như bạn đã biết! Và có trình biên dịch sẽ tạo ra một lỗi/cảnh báo.Xcode 7 là phần mềm beta, báo cáo nó như là một lỗi cho Apple và hy vọng họ sẽ sửa chữa nó. – CRD

+0

Cảm ơn bạn đã làm rõ! – lvp

+0

Tôi không tin đó là lỗi. Xem bài viết lớn của tôi dưới đây với mã mẫu và tại sao nó hoạt động chính xác. – drekka

Trả lời

10

Tôi vừa mới chẩn đoán điều này một số chi tiết và tôi không nghĩ đây là lỗi. Các mã sau đây cho thấy một loạt các tùy chọn và tại sao mỗi sẽ hoặc sẽ không biên dịch. Lưu ý: Điều này dựa trên những dự đoán của tôi về cách mọi thứ hoạt động. Nó có thể khác với cách Apple giải thích nó.

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wunused-variable" 
-(void) testGenericArrays { 

    NSString *aString = @"abc"; 
    NSNumber *aNumber = @(55); 

    NSArray<NSString *> *arr1 = @[aString, aNumber]; 
    // Compiles because the RHS is an un-typed array at compilation time. 

    NSArray<NSString *> *arr2 = @[aString, @(20)]; 
    // Compiles because the RHS is an un-typed array at compilation time. 

    NSArray<NSString *> *arr3 = [NSArray<NSString *> arrayWithObjects:aString, aNumber, @(20), nil]; 
    // Compiles because the type erasure for arrayWithObjects only types the first argument which is a NSString. 
    // The rest of the arguments are a vaList which is not checked during header processing. 

    NSArray<NSString *> *arr4 = [NSArray<NSString *> arrayWithObjects:@(20), nil]; // <- Error! 
    NSArray<NSString *> *arr5 = [NSArray<NSString *> arrayWithObjects:aNumber, nil]; // <- Error! 
    // Neither of these two compile because the first argument is now a NSNumber and is checked. 

    NSArray<NSString *> *arr6 = [NSArray<NSString *> arrayWithObject:aNumber]; // <- Error! 
    // Doesn't compile because the argument is checked during header processing. 

    NSArray<NSString *> *arr7 = [NSArray arrayWithObject:aNumber]; 
    // Compiles because the RHS is an un-typed array at compilation time. 

    NSMutableArray<NSString *> *arr8 = [[NSMutableArray alloc] init]; 
    [arr8 addObject:aNumber]; // <- Error! 
    // Doesn't compile because the LHS is a typed array and we are adding to it. 
} 
#pragma clang diagnostic pop 

Hy vọng điều này sẽ làm rõ mọi thứ cho mọi người. Cảm thấy tự do để cắt và dán vào một bài kiểm tra đơn vị và thử nó ra cho chính mình.

0

Tôi đồng ý rằng đây là lỗi. Tôi đã thử nghiệm một phiên bản đơn giản hơn trong trường hợp của bạn và nó vẫn không thành công.

NSString *first = @"1"; 
NSString *second = @"2"; 
NSString *third = @"3"; 
NSNumber *test = @(55); 

NSArray <NSString*>* arr = @[first, second, third, test, @(20)]; 

Nó dường như không phải là vấn đề với cú pháp ngữ pháp mảng. Dòng này vẫn không tạo ra lỗi.

NSArray <NSString*>* anotherArray = [NSArray arrayWithObjects:first, second, third, test, @(20), nil]; 
2

Đừng cho rằng Apple đang thêm generics vào Obj-C vì họ muốn cải thiện Obj-C. Lý do thực sự là tất cả các khung công tác iOS/OS X được viết bằng Obj-C rất khó sử dụng trong Swift - bạn phải truyền mọi thứ từ AnyObject.

Thêm Generics vào Obj-C cho phép Apple gắn thẻ chính xác các phương pháp, ví dụ:

@property(nonatomic, readonly, copy) NSArray <__kindof UIView *> *subviews 

Điều quan trọng ở đây là bây giờ Swift có thể làm việc với các khung tốt hơn nhiều. Việc triển khai cảnh báo/lỗi khi lạm dụng Generics trong Obj-C không quan trọng vì vậy chúng tôi có thể mong đợi rất nhiều lỗi ở đó.

Tôi khuyên bạn nên báo cáo lỗi nhưng không mong đợi nó sẽ được khắc phục sớm.

0

Tôi vừa xem qua bài đăng này và tôi không nhận được kết quả tương tự. Tôi đã cắt và dán mã vào XCode để xác nhận và tất cả các ví dụ trên tạo ra lỗi (tôi đã cảnh báo được đặt thành lỗi). Vì vậy, tôi không thấy lỗi. Hoặc là có hoặc có một cài đặt trình biên dịch ở đâu đó khác nhau giữa chúng tôi.

+0

Tôi đã thử nó với Xcode 7 beta, nó thành công để biên dịch –

+0

Tôi không thể giải thích tại sao nó có vẻ làm việc cho một số và không phải những người khác. Tôi đã sử dụng Generics cho tuần trước hoặc lâu hơn và họ đang tạo ra tất cả các cảnh báo trình biên dịch mà tôi mong đợi họ tạo ra. Tôi sẽ đề nghị kiểm tra thông qua các thiết lập xây dựng và điều này có vẻ là nguyên nhân có khả năng nhất của sự khác biệt đối với tôi. Có lẽ vì tôi có tất cả các cảnh báo được đặt là lỗi mà tôi đang làm việc. – drekka

+0

Hãy quên nhận xét cuối cùng của tôi. Tôi đang kiểm tra một số thứ khác. – drekka

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