2010-01-11 29 views
14

Tôi có cấu trúc đối tượng sau:Mục tiêu c isKindOfClass sai lầm?

Thú cưng, Chó và mèo. Như bạn mong đợi Chó và Mèo được thừa hưởng từ Động vật.

Và tôi đã là một lớp trang trại:

@implementation AnimalFarm 

-(Animal*) createAnimal:(AnimalType)type{ 

    switch (type) { 

    case CAT: 
     return [Cat new]; 

    case DOG: 
     return [Dog new]; 

    default: 
     return [Animal new]; 
    } 

} 

@end 

và tôi đã cố gắng để kiểm tra đơn vị:

AnimalFarm *farm = [AnimalFarm new]; 

    Animal *dog = [farm createAnimal:DOG]; 
    Animal *cat = [farm createAnimal:CAT]; 

    STAssertTrue([cat isMemberOfClass:[Cat class]],@"cat is not a cat!"); 
    STAssertTrue([dog isMemberOfClass:[Dog class]],@"Dog is not a dog!"); 

    STAssertTrue([cat isKindOfClass:[Animal class]],@"Cat is not an animal!"); 
    STAssertTrue([dog isKindOfClass:[Animal class]],@"Cat is not an animal!"); 

Thực hiện các lớp:

@interface Cat : Animal { 

} 


@end 

@implementation Cat 

    -(NSString*) say{ 
    return @"miau"; 
} 

@end 

thực hiện của con chó là tương tự.

nhưng không isKindOfClass hoặc isMemberOfClass làm việc như tôi mong đợi ....

Tôi có thiếu cái gì?


Khi tôi sử dụng IF thay vì chuyển đổi thì mọi thứ diễn ra tốt đẹp ... nhưng sự khác biệt là gì?

Thực hiện createAnimal mà hoạt động:

-(Animal *) createAnimal:(AnimalType)type { 

    if (type == DOG) { 
    return [Dog new]; 
    } else if (type == CAT) { 
    return [Cat new]; 
    } else { 
    return [Animal new]; 
    } 
+1

Để làm rõ: Cả hai 'isMemberOfClass:' và 'isKindOfClass:' đang trả về NO trong các ví dụ đó? – Chuck

+0

Và bạn có nhận được bất kỳ cảnh báo nào trong quá trình biên dịch không? – Chuck

+1

Chúng ta có thể thấy định nghĩa 'CAT' và' DOG' không? Ngoài ra, những gì bạn có nghĩa là "không làm việc như tôi mong đợi"? Kết quả của xác nhận là gì? – Tim

Trả lời

39

isMemberOfClass: sẽ chỉ trả lại YES nếu lớp của dụ là giống hệt nhau, tuy nhiên isKindOfClass: sẽ trở lại YES nếu lớp của ví dụ là như nhau, hoặc một lớp con của các trao lớp học.

Ví dụ này sẽ ra No!:

BOOL result = [[NSMutableArray array] isMemberOfClass:[NSArray class]]; 
NSLog (@"%@", result? @"Yes!" : @"No!"); 

Nhưng ý chí đầu ra này Yes!:

BOOL result = [[NSMutableArray array] isKindOfClass:[NSArray class]]; 
NSLog (@"%@", result? @"Yes!" : @"No!"); 

này là vì một NSMutableArray là một loại của NSArray, nhưng nó không phải là một thành viên của lớp NSArray (nếu không nó sẽ không phải là một NSMutableArray).

Xuyên suốt nền tảng và ca cao, có một số "nhóm lớp". Bạn có thể đọc thêm về điều này trong tài liệu trên Apple's developer web site. Do tính chất của các nhóm lớp, nếu bạn có thể tạo ra một đối tượng NSString, nó có thể thất bại trong thử nghiệm isMemberOfClass:[NSString class].

Nếu không isKindOfClass: hoặc isMemberOfClass: được trả lại giá trị đúng, xem những gì lớp đối tượng thực tế là với

NSLog(@"cat class = %@, dog class = %@", [cat className], [dog className]); 

Nếu chúng được trở về bất cứ điều gì khác so với những gì họ có nghĩa vụ phải, sau đó có một vấn đề với bạn lớp trang trại.

+0

đầu ra của nhật ký là: cat class = Cat, lớp chó = Dog Tôi đã cố gắng thay đổi mới bằng phân bổ và init nhưng kết quả vẫn như cũ. Như bạn có thể thấy tôi so sánh các lớp chính xác bằng cách sử dụng isMemberOfClass vì vậy Nó sẽ trả về YES cũng như isKindOfClass – Vitek

3

Sự cố của bạn nằm ở nơi khác.

Tôi đã tạo các lớp học Animal, DogCat của bạn và bốn trường hợp bạn đã vượt qua.Để tham khảo, đây là mã của tôi: http://pastie.org/774468

Nó ra:

2010-01-11 19:45:10.259 EmptyFoundation[83698:a0f] [cat isMemberOfClass:[Cat class]] PASSED 
2010-01-11 19:45:10.265 EmptyFoundation[83698:a0f] [dog isMemberOfClass:[Dog class]] PASSED 
2010-01-11 19:45:10.265 EmptyFoundation[83698:a0f] [cat isKindOfClass:[Animal class]] PASSED 
2010-01-11 19:45:10.273 EmptyFoundation[83698:a0f] [dog isKindOfClass:[Animal class]] PASSED 

EDIT:

Tôi cho rằng đã có một khả năng nhỏ mà đối tượng AnimalFarm của bạn là nguồn gốc của các lỗi, nhưng tôi chỉ đã thử tạo các vật thể như vậy và có cùng kết quả (mã: http://pastie.org/774480):

2010-01-11 19:51:35.144 EmptyFoundation[83741:a0f] [cat isMemberOfClass:[Cat class]] PASSED 
2010-01-11 19:51:35.156 EmptyFoundation[83741:a0f] [dog isMemberOfClass:[Dog class]] PASSED 
2010-01-11 19:51:35.157 EmptyFoundation[83741:a0f] ![ant isMemberOfClass:[Cat class]] PASSED 
2010-01-11 19:51:35.157 EmptyFoundation[83741:a0f] [cat isKindOfClass:[Animal class]] PASSED 
2010-01-11 19:51:35.157 EmptyFoundation[83741:a0f] [dog isKindOfClass:[Animal class]] PASSED 
2010-01-11 19:51:35.158 EmptyFoundation[83741:a0f] [ant isKindOfClass:[Animal class]] PASSED 

EDIT # 2:Dựa trên quan sát của bạn rằng nếu ... else if statement hoạt động nhưng câu lệnh switch thì không, tôi đã sửa đổi mã mà tôi đã đăng ở trên để sử dụng câu lệnh switch .... và nó hoạt động tốt. Vì vậy, nhận xét/câu hỏi của tôi là viết tắt: Trong báo cáo if/switch của bạn, bạn đang sử dụng các hằng số DOGCAT này. Những người được xác định ở đâu?

+0

Vâng, tôi đã cố gắng tạo các cá thể bằng cách sử dụng [Cat new] trực tiếp và mọi thứ hoạt động .... do đó vấn đề nằm trong trang trại – Vitek

+0

@ Vitek - bạn định nghĩa 'CAT' và' DOG' như thế nào? –

+0

ý của bạn là gì? Mã của tôi được hiển thị ở trên ... – Vitek

-9

Bạn đang nghỉ giải lao, đó là lý do tại sao nút chuyển của bạn không hoạt động. Nó sẽ giống như thế này.

switch (type) { 

case CAT: 
    return [Cat new]; 
break; 
case DOG: 
    return [Dog new]; 
break; 
default: 
    return [Animal new]; 
break; 
} 
+9

trả về đã hoạt động như một ngắt – Tim