2010-09-12 44 views
5

Tôi có một phương thức lấy NSMutableArray làm tham số và tôi muốn nó trả về mảng đó, một mảng khác được tạo trong phương thức và một int được tạo bởi phương pháp. Tôi nhận ra điều này có thể được thực hiện bằng cách tạo một mảng có tất cả các đối tượng trong nó, và trả về, sau đó loại bỏ chúng khỏi mảng bên ngoài phương thức, nhưng có cách nào khác để trả về nhiều đối tượng không?Trả về nhiều đối tượng từ một phương thức trong Objective-C

+0

Về cơ bản, cách dễ nhất để thực hiện việc này là chỉ đặt các giá trị trong từ điển hoặc mảng. – Regan

Trả lời

7

Sử dụng NSDictionary để trả lại nhiều giá trị là cách thông thường để thực hiện việc này trong Obj-C.

Chữ ký phương pháp sẽ giống như thế này:

-(NSDictionary *)doSomeStuffThatReturnsMultipleObjects; 

và bạn sẽ muốn xác định các phím từ điển của bạn trong các tập tin thích hợp.

// Header File 
extern NSString *const JKSourceArray; 
extern NSString *const JKResultsArray; 
extern NSString *const JKSomeNumber; 

// Implementation File 
NSString *const JKSourceArray = @"JKSourceArray"; 
NSString *const JKResultsArray = @"JKResultsArray"; 
NSString *const JKSomeNumber = @"JKSomeNumber"; 

Ưu điểm so với sử dụng một mảng là các thứ tự của các yếu tố và sự hiện diện/vắng mặt của các yếu tố không quan trọng, làm cho nó dễ dàng hơn để mở rộng trong tương lai, nếu bạn muốn quay trở lại đối tượng bổ sung. Nó cũng linh hoạt hơn và có thể mở rộng hơn so với truyền qua tham chiếu.

2

Một cách khác bạn có thể làm là cho phép người dùng chuyển một con trỏ mà họ muốn sử dụng để giữ dữ liệu. Đây là một mẫu trả về một mảng và sử dụng con trỏ để cung cấp cho bạn một giá trị int và một mảng khác. EDIT ok đây là phiên bản làm việc tôi chỉ thử nghiệm nó bản thân mình:

- (NSMutableArray*)doStuff:(int*)container returnedArray:(NSMutableArray*)arrayContainer{ 
    int a = 4; 
    *container = a; 
    [arrayContainer removeAllObjects]; 
    [arrayContainer addObject:@"object"]; 
    return [NSMutableArray arrayWithObjects:@"object",nil]; 
} 

Bằng cách đó bạn có thể nói như sau:

int value = 0; 
NSMutableArray* new = [NSMutableArray array]; 
[self doStuff:&value returnedArray:new]; 

Và nó về cơ bản hoạt động giống như một sự trở lại!

+0

Mặc dù kỹ thuật chung mà bạn mô tả là một kỹ thuật được sử dụng trong các chương trình thực, mã đó hoàn toàn bị hỏng và sẽ không làm những gì được dự định. Bạn dường như có một số quan niệm sai lầm về cách con trỏ hoạt động, và cũng về phạm vi biến. – Chuck

+0

Vâng, tôi nghĩ điều này có vẻ hơi lệch. Cảm ơn cho ý tưởng mặc dù. – Regan

+0

@Chuck Tôi đã không thử nghiệm nó Tôi đã chỉ đưa ra một mẫu của khái niệm và tôi đã viết rằng trong thời gian rất ít. Tôi chỉ cố gắng đưa anh ta đi đúng hướng. –

0

Bạn có thể cân nhắc việc trả về cấu trúc.

typedef struct { 
    NSMutableArray *array1; 
    NSArray *array2; 
    NSInteger integer; 
} MyAwesomeReturnValue; 

phương pháp của bạn bây giờ có thể trông như thế này:

- (MyAwesomeReturnValue)myAwesomeMethod:(NSMutableArray *)parameter 
{ 
    MyAwesomeReturnValue retval; 
    retval.array1 = parameter; 
    retval.array2 = [NSArray array]; 
    retval.integer = 5; 

    return retval; 
} 

Và bạn muốn sử dụng nó như:

- (void)anotherAwesomeMethod 
{ 
    NSMutableArray *array = [NSMutableArray array]; 
    MyAwesomeReturnValue returnedValue = [self myAwesomeMethod:array]; 

    NSLog(@"%@", returnedValue.array1); 
    NSLog(@"%@", returnedValue.array2); 
    NSLog(@"%d", returnedValue.integer); 
} 

Hy vọng rằng sẽ giúp. ;)

+2

Tôi không thích ví dụ 'myAwesomeMethod'. Bạn đang tạo một tham số cục bộ có tên là retval và trả về kết quả đó. Nhưng ngay khi bạn bật ngăn xếp, bạn sẽ mất thông số cục bộ đó. Nó sẽ khác nếu đó là một đối tượng, nhưng đây chỉ là cấu trúc C chuẩn. – Rickster

+0

Ehm đó là sự thật. Lol .. –

+0

@Christian Schnorr, Làm thế nào bạn có thể thiết lập 'NSMutableArray' trong' struct'. Nên có lỗi. – Tulon

9

Những cách điển hình để vượt qua trở lại nhiều giá trị là:

  • Thêm tham số bổ sung bằng cách tham chiếu (ví dụ.thường NSErrors được truyền theo cách này)
  • Vượt qua chúng trở lại ở một số đối tượng struct hay khác, điển hình là một NSDictionary hoặc một lớp tùy chỉnh

Trên đây là giải pháp tốt cho nhiều tình huống, nhưng đây là một giải pháp khác mà có thể làm việc tốt nhất trong những tình huống khác:

Thêm một khối phương pháp của bạn:

- (void)myMethodWithMultipleReturnObjectsForObject:(id)object returnBlock:(void (^)(id returnObject1, id returnObject2))returnBlock 
{ 
    // do stuff 

    returnBlock(returnObject1, returnObject2); 
} 

Sau đó sử dụng phương pháp này như sau:

[myMethodWithMultipleReturnObjectsForObject:object returnBlock:^(id returnObject1, id returnObject2) { 
    // Use the return objects inside the block 
}]; 

Đối tượng trả về trong ví dụ trên chỉ có thể sử dụng trong khối, vì vậy nếu bạn muốn giữ chúng xung quanh để sử dụng bên ngoài khối, chỉ cần đặt một số __block vars.

// Keep the objects around for use outside of the block 
__block id object1; 
__block id object2; 
[myMethodWithMultipleReturnObjectsForObject:object returnBlock:^(id returnObject1, id returnObject2) { 
    object1 = returnObject1; 
    object2 = returnObject2; 
}]; 
+0

Bạn có thể giải thích thêm một chút về điều đó không? Làm thế nào tôi có thể khai báo khối trong trường hợp này? – Tulon

+0

@Tulon Tôi không chắc chắn ý của bạn là gì. Tôi đã hiển thị tuyên bố của khối trong đoạn mã đầu tiên trong ví dụ của tôi. –

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