Аргументы по ссылке в Objective-C - PullRequest
20 голосов
/ 26 июля 2010

Я пытаюсь передать NSString по ссылке, но он не работает.

Это функция:

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

и это звонок:

NSString *file;

[function fileName:file];

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

Что я должен сделать, чтобы передать мою строку по ссылке?

Ответы [ 5 ]

63 голосов
/ 26 июля 2010

Если вы хотите вернуть значение, то возвращает значение .Передача по ссылке в Какао / iOS в основном ограничена NSError**.

Дано:

+(void)fileName:(NSString *) file

Затем выполните:

+(NSString *) fileName;

И покончим с этим.

Если вам нужно возвращать более одного значения за раз, которое требует структуры или, чаще, класса.

В Objective-C, передавайте по ссылке запахи, как выделать это неправильно.

Передача по ссылке в Objective-C зарезервирована в основном для возврата NSError* информации о восстанавливаемом сбое, где возвращаемое значение самого метода указывает, была ли запрошенная задача успешной или нет (вы можете передать NULL какаргумент NSError**, позволяющий оптимизировать метод, создавая указанные метаданные ошибки).

Передача по ссылкам также используется для получения внутреннего состояния объектов, где возвращаемое значение фактически является многозначным.Т.е. методы из AppKit вроде следующего.В этих случаях аргументы передачи по ссылке обычно являются необязательными или действуют как вторичные возвращаемые значения.

Они довольно редко используются в 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);
31 голосов
/ 26 июля 2010

Я считаю, что вы ищете:

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

Что здесь действительно сделано, так это то, что мы работаем с указателем на указатель на объект. Для получения дополнительной информации проверьте направляющие C (да, просто C) на «разыменование указателя».

(... Но, как уже неоднократно указывалось, в этом конкретном примере нет никакой причины передавать по ссылке вообще: просто вернуть значение.)

3 голосов
/ 14 августа 2012

Попробуйте это

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

и отправьте файл как &file как:

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

надеюсь, что это сработает.

3 голосов
/ 20 февраля 2012

Передача указателя на ваш объект - это способ передачи по Objective C (и C) по ссылке.

Я согласен с «bbum» в том, что осознанная необходимость пройти по ссылке - это сигнал к размышлению о том, что вы делаете; однако это ни в коем случае не означает, что нет законных оснований для передачи по ссылке.

Вы не должны создавать классы волей-неволей каждый раз, когда у вас есть функция или метод, которые должны возвращать более одного значения. Подумайте, почему вы возвращаете более одного значения, и если имеет смысл создать класс для этого, то сделайте это. В противном случае просто передайте указатели.

-Просто мои 2 цента

0 голосов
/ 26 июля 2010

Я подозреваю, что это потому, что NSString является неизменным.Вы пробовали NSMutableString ?

...