2010-07-26 6 views
19

NSString을 참조로 전달하려고 시도하지만 작동하지 않습니다. Objective-C에서 참조하는 인수

는 기능입니다 :

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

이 통화입니다 : 내가 참조로 내 문자열을 전달하기 위해 무엇을해야

NSString *file; 

[function fileName:file]; 

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

?

답변

30

난 당신이 찾고있는 생각합니다. 자세한 정보는 C (yup, just plain C) 가이드에서 "포인터 비 참조"를 확인하십시오.

(...하지만이 특정 예에서, 반복적으로 지적 된 바와 같이, 모든 참조로 전달하는 이유가 없습니다 : 그냥 값을 반환합니다.)

+5

+1 메서드 호출은 [function fileName : & file] –

+2

으로 변경되어야합니다. @bbum : 매개 변수 *는 입력/출력 매개 변수 일 수 있지만 그 때도 가능합니다. . . – dreamlax

-2

NSString이 변경 불가능하기 때문에 이것이 의심 스럽습니다. NSMutableString을 사용해 보셨습니까? 우리가 객체에 대한 포인터에 대한 포인터 와 협력하고 정말로 여기에 끝났다입니다

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

:

+0

가변 문자열을 사용하면 변수를 새 객체로 '설정할 수 없으므로 주어진 예제에서는 엄격하게 작동하지 않습니다. 하지만 상황에 따라 (double object ptr 대신) (+1)하는 것이 가장 좋은 방법입니다. – Akusete

+0

하나의 옵션은 NSMutableString을 전달한 다음'setString :'을 사용하는 것이지만 " 참조로 ". – andyvn22

+0

@andyvn : 당신 말이 맞아요, 제 요점은 (종종 그렇듯이) 질문에 기술적으로 답을 쓰는 것이고, 가장 좋은 해결책은 문제가 같은 것이 아니라는 것입니다. – Akusete

63

당신이 값을 반환 할 경우, 값을으로 반환하십시오. Cocoa/iOS에서 참조에 의한 패스는 주로 NSError**으로 제한됩니다. 을 감안할 때

:

+(void)fileName:(NSString *) file 

는 다음을 수행하십시오

+(NSString *) fileName; 

그리고는 그것을 함께 할 수.

한 번에 둘 이상의 값을 반환해야하는 경우 구조 또는 더 자주 클래스를 요구합니다.

Objective-C에서 참조로 전달하는 것은 잘못하고있는 것처럼 냄새가납니다. 오브젝티브 C 참조하여


패스는 메서드의 반환 값 자체가 요청 된 작업이 성공 또는 실패 여부를 나타냅니다 복구 실패에 대한 NSError* 정보를 반환하기위한 대부분 예약되어 (당신은 NULL를 전달할 수 있습니다 상기 방법이 상기 에러 메타 데이터의 생성을 최적화하는 것을 허용하는 인수는 NSError**).

참조로 전달은 반환 값이 사실상 다중 값인 객체의 내부 상태를 검색하는데도 사용됩니다. 나는. AppKit의 메소드는 다음과 같습니다. 이 경우, 참조 전달 인수는 일반적으로 선택적이거나 2 차 리턴 값으로 작용합니다.

API를 통해 거의 사용되지 않습니다. 참조 용으로 사용하는 것은 확실하지만 위와 같이하면 응용 프로그램 코드에서 매우 드물고 희귀해야합니다. 많은 경우와 아래의 경우에 잠재적으로 더 나은 패턴은 상태를 캡슐화 한 다음 참조로 전달하는 대신 클래스의 인스턴스를 반환 할 수있는 클래스를 만드는 것입니다.

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

"Objective-C에서는 참조를 통한 전달이 잘못하고있는 것처럼 냄새가납니다." 설명해 주시겠습니까? 그것을하는 것의 아래쪽면은 무엇입니까? – Philip007

+2

@bbum - 그리고 만약 내가 2 params 다시 필요합니까 ??? 나는 동의하지 않는다. – Gal

+2

@gal 실제 답변을 읽었습니까? 두 개의 매개 변수가 필요한 경우 구조 또는 클래스를 사용하십시오. 매우 드물게 ref를 사용하여 올바른 패턴을 전달하지는 않습니다. – bbum

3

개체에 대한 포인터를 전달하는 것은 참조로 전달하는 Objective C (및 C) 방법입니다.

나는 참조로 전달해야 할 필요성이 당신이하고있는 일에 대해 생각할 신호라는 'bbum'에 동의합니다. 그러나 참조로 합격해야하는 합법적 인 이유가 없다는 것은 결코 아닙니다.

둘 이상의 값을 반환해야하는 함수 나 메서드가있을 때마다 클래스를 만들 필요가 없습니다. 왜 하나 이상의 값을 반환하는지 그리고 그 값을위한 클래스를 만드는 것이 합리적인지 생각해보십시오. 그렇지 않으면 포인터를 전달하십시오. 제 2 센트

3

- 그냥

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

을 시도하고 같은 &file로 파일을 보내 :이 작동

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

희망.