2010-07-26 32 views
19

Tôi đang cố gắng chuyển một tham chiếu NSString nhưng nó không hoạt động.Đối số bằng cách tham chiếu trong Objective-C

Đây là chức năng:

+(void)fileName:(NSString *) file 
{ 
    file = @"folder_b"; 
} 

và đây là cuộc gọi:

NSString *file; 

[function fileName:file]; 

nslog(@"%@",file); // and there is nothing in the string.... 

Những gì tôi phải làm gì để vượt qua chuỗi của tôi bằng cách tham khảo?

Trả lời

30

Tôi tin rằng bạn đang tìm kiếm:

+ (void)fileName:(NSString **)file 
{ 
    *file = @"folder_b"; 
} 

gì thực sự thực hiện ở đây là chúng ta đang làm việc với một con trỏ đến một con trỏ đến một đối tượng. Kiểm tra các hướng dẫn C (yup, just plain C) để biết "dereference pointer" để biết thêm thông tin.

(... Nhưng như đã được chỉ ra nhiều lần, trong ví dụ đặc biệt này, không có lý do để vượt qua bằng cách tham chiếu ở tất cả: chỉ cần trả về một giá trị.)

+5

+1 Cuộc gọi phương thức sau đó sẽ phải được thay đổi thành [function fileName: & file] –

+2

@bbum: Tham số * có thể * là tham số vào/ra, nhưng ngay cả sau đó. . . – dreamlax

-2

Tôi nghi ngờ điều này là do NSString không thay đổi. Bạn đã thử NSMutableString chưa?

+0

Sử dụng chuỗi có thể thay đổi không thể 'đặt' biến thành đối tượng mới, do đó, nghiêm ngặt sẽ không hoạt động trong ví dụ đã cho. Nhưng tùy thuộc vào hoàn cảnh, nó có khả năng là cách tốt nhất để đi (+1) (thay vì ptr đối tượng đôi) – Akusete

+0

Một tùy chọn sẽ là chuyển một 'NSMutableString' và sau đó sử dụng' setString: ', nhưng điều đó sẽ không được" bằng cách tham khảo ". – andyvn22

+0

@andyvn: Bạn nói đúng, quan điểm của tôi là (như thường là trường hợp) về mặt kỹ thuật viết câu trả lời cho câu hỏi, và giải pháp tốt nhất là một vấn đề không giống nhau. – Akusete

63

Nếu bạn muốn trả lại một giá trị, sau đó trả lại giá trị. Vượt qua tham chiếu trong Cocoa/iOS được giới hạn phần lớn là NSError**.

Given:

+(void)fileName:(NSString *) file 

Sau đó làm:

+(NSString *) fileName; 

Và được thực hiện với nó.

Nếu bạn cần trả lại nhiều hơn một giá trị tại một thời điểm, điều đó đòi hỏi một cấu trúc hoặc, thường xuyên hơn, một lớp học.

Trong mục tiêu-C, chuyển qua các mùi tham chiếu như bạn đang làm sai.


đèo bằng cách tham khảo trong Objective-C được dành chủ yếu cho trở NSError* thông tin về một thất bại thu hồi, nơi mà các giá trị trả về của phương pháp riêng của mình chỉ ra hay không nhiệm vụ yêu cầu thành công hay thất bại (bạn có thể vượt qua NULL như đối số NSError** để cho phép phương pháp tối ưu hóa việc tạo siêu dữ liệu lỗi đã nói).

Vượt qua tham chiếu cũng được sử dụng để truy xuất trạng thái bên trong của các đối tượng trong đó giá trị trả lại thực sự là một giá trị đa. I E. các phương thức từ AppKit như sau. Trong những trường hợp này, đối số truyền qua tham chiếu thường là tùy chọn hoặc hoạt động như các giá trị trả về thứ cấp.

Chúng được sử dụng khá ít trên API. Có chắc chắn sử dụng để vượt qua bằng cách tham khảo, nhưng - như đã nói ở trên - làm như vậy nên được khá hiếm và hiếm vẫn còn trong mã ứng dụng. Trong nhiều trường hợp - và trong một số trường hợp dưới đây, có khả năng - một mô hình tốt hơn là tạo một lớp có thể đóng gói trạng thái và sau đó trả về một thể hiện của lớp đã nói thay vì truyền tham chiếu.

NSWorkspace.h:- (BOOL)getInfoForFile:(NSString *)fullPath application:(NSString **)appName type:(NSString **)type; 
NSTextView.h:- (void)smartInsertForString:(NSString *)pasteString replacingRange:(NSRange)charRangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString; 
NSAttributedString.h:- (BOOL)readFromURL:(NSURL *)url options:(NSDictionary *)options documentAttributes:(NSDictionary **)dict; 
NSNib.h:- (BOOL)instantiateWithOwner:(id)owner topLevelObjects:(NSArray **)topLevelObjects NS_AVAILABLE_MAC(10_8); 
NSSpellChecker.h:- (NSRange)checkGrammarOfString:(NSString *)stringToCheck startingAt:(NSInteger)startingOffset language:(NSString *)language wrap:(BOOL)wrapFlag inSpellDocumentWithTag:(NSInteger)tag details:(NSArray **)details NS_AVAILABLE_MAC(10_5); 
+2

"Trong mục tiêu-C, đi qua mùi tham chiếu như bạn đang làm sai." Bạn có thể giải thích điều đó không? Phía bên dưới làm gì? – Philip007

+2

@bbum - Và nếu tôi cần 2 tham số trở lại ??? Tôi không đông y vơi bạn. – Gal

+2

@gal bạn đã đọc câu trả lời thực sự chưa? Nếu bạn cần hai tham số, hãy sử dụng một cấu trúc hoặc một lớp. Rất hiếm khi được truyền bằng cách thay đổi mẫu phù hợp để sử dụng. – bbum

3

Chuyển con trỏ đến đối tượng của bạn là mục tiêu C (và C) đi qua tham chiếu.

Tôi đồng ý với 'bbum' rằng nhu cầu nhận thức được thông qua tham chiếu là tín hiệu để suy nghĩ về những gì bạn đang làm; tuy nhiên, không có nghĩa là trường hợp không có lý do chính đáng để vượt qua bằng cách tham chiếu.

Bạn không nên tạo các lớp dữ liệu mỗi lần bạn có hàm hoặc phương thức cần trả về nhiều giá trị. Hãy xem xét lý do tại sao bạn đang trả về nhiều hơn một giá trị và nếu nó có ý nghĩa để tạo một lớp cho điều đó thì hãy làm như vậy. Nếu không, chỉ cần vượt qua trong con trỏ.

-Cũng 2 cent tôi

3

Hãy thử điều này

+(void)filename:(NSString **)file { 
    *[email protected]"folder_b"; 
} 

và gửi các tập tin như &file như:

NSString *file; 
[function fileName:&file]; 
nslog(@"%@",file); 

hy vọng điều này sẽ làm việc.

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