2011-09-02 36 views
8

Tôi có một lớp A với thuộc tính NSString *name. Nếu có một NSArray và thêm nhiều đối tượng A vào mảng này, có cần phải truyền mỗi khi tôi truy xuất một đối tượng không? tức làNSArray đối tượng và Đúc

NSString* n = (NSString*)[arr objectAtIndex:1]; 

Hoặc có cách nào khác để làm điều đó giống như trong java nơi bạn có ArrayList<A> arr?

Trả lời

20

NSArray không lưu trữ thông tin về các loại đối tượng chứa trong chúng. Nếu bạn biết chắc chắn các loại của các đối tượng trong mảng, bạn có thể thực hiện một dàn diễn viên, hoặc là ngầm hay rõ ràng:

NSString *n = [arr objectAtIndex:1]; // implicit type conversion (coercion) from id to NSString* 
NSString *n = (NSString *)[arr objectAtIndex:1]; // explicit cast 

Không có sự khác biệt về chi phí thời gian chạy giữa phôi ngầm và rõ ràng, nó chỉ là một vấn đề của phong cách. Nếu bạn nhận được loại sai, sau đó những gì rất có thể sẽ xảy ra là bạn sẽ nhận được sự sợ hãi unrecognized selector sent to instance 0x12345678 ngoại lệ.

Nếu bạn có một mảng không đồng nhất của các loại đối tượng khác nhau, bạn cần phải sử dụng phương pháp isKindOfClass: để kiểm tra lớp của đối tượng:

id obj = [arr objectAtIndex:1]; 
if ([obj isKindOfClass:[NSString class] ]) 
{ 
    // It's an NSString, do something with it... 
    NSString *str = obj; 
    ... 
} 
+2

Cần lưu ý rằng không có cách nào để phân biệt giữa NSStrings và NSMutableStrings khi chạy - tất cả đều trả lời CÓ cho 'isKindOfClass: [NSMutableString class]'. – Chuck

+0

@Chuck: Tôi không biết điều đó. Làm thế nào mà? –

+0

@Chuck: Tôi nhận thấy rằng NSString cũng trả về YES thành '[myNSString respondsToSelector: @" appendFormat:]; '. ISTM mà các chuỗi có thể thay đổi và không thay đổi đều được thực thi bởi __NSCFString và có một số cờ bên trong cho biết nó có thể thay đổi hay không Nếu bạn gọi '[myNSString appendFormat: @" world "];' bạn sẽ nhận được một ngoại lệ, nhưng không phải là một ngoại lệ cho biết nó không đáp ứng với bộ chọn. Rõ ràng 'appendFormat:' kiểm tra cờ bất biến và nếu nó được đặt, nó Một chuỗi có thể thay đổi và không thay đổi được, trên thực tế, cùng một lớp, '__NSCFString'. –

1

Đây là cách để thực hiện. Bạn thực sự có thể thực hiện thao tác trên mà không cần gửi trả về vì bạn vẫn đang đọc nó vào một NSString.

-2

đây là cách:

NSMutableArray *objectsArray = [[NSMutableArray alloc] init]; 

A *a= [[A alloc] init]; 

[objectsArray addObject:a]; 

[a release]; 

Bạn không cần phải lo lắng về các loại với đặc tính

+0

Đó rò rỉ mã ... – Daniel

+2

Trên thực tế không có, thêm vào mảng giữ lại đối tượng sao cho sau đoạn mã đó bạn có số giữ là +2, vì vậy bạn thực sự cần phải loại bỏ mục đó và giải phóng nó để nó không bị rò rỉ, tất cả và tất cả điều này là xấu, tôi nên nói điều này mã có thể dẫn đến rò rỉ .. – Daniel

+0

Daniel có quyền chỉ ra rằng đây là kiểu kém. Chỉ có một tham chiếu đến thể hiện của 'A', là thông qua mảng, nhưng cả mảng và mã' alloc'ing đều có quyền sở hữu trên nó./cc @Chuck –

11

NSArray 's objectAtIndex: trả về một biến kiểu id. Điều này tương đương với việc trả lại một số Object trong Java— "chúng tôi không thể đảm bảo nhiều về loại biến này." Tuy nhiên, trong mục tiêu-C, bạn có thể gửi tin nhắn tới các biến số id mà không cần trình biên dịch phàn nàn. Vì vậy, vì bạn biết rằng mảng chỉ chứa A trường hợp, bạn nên gửi thông báo name. Ví dụ, sau đây sẽ biên dịch mà không cần cảnh báo:

NSString *name = [[array objectAtIndex:0] name]; 

Tuy nhiên, nếu bạn muốn sử dụng ký hiệu dấu chấm (ví dụ [array objectAtIndex:0].name), bạn sẽ cần phải cast id một A * như ở đây:

NSString *name = ((A *)[array objectAtIndex:0]).name; 
+0

hoàn hảo .. chỉ là thông tin tôi đang tìm kiếm – Tim

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