Objective-c и использование NSString в качестве параметра функции - PullRequest
2 голосов
/ 03 июля 2011

У меня странный вопрос (ко мне, во всяком случае).

Я вызываю функцию в моей программе Objective-C и передаю три аргумента: домашний объект, NSMutableArray иNSString.

Прототип функции выглядит следующим образом ....

 int LoadNoteTableArray (Entryfile* EntryfileName, 
      NSMutableArray* NSMutableArrayInputEntry, NSString* title_string);

Я называю это изнутри main следующим образом ...

 Entryfile* Entryfile1 = [[Entryfile alloc] init];
 NSMutableArray *NoteTableArray = [[NSMutableArray alloc] initWithCapacity:1];
 NSString*          title_string;

title_string = @"test string";

checkerror = LoadNoteTableArray (Entryfile1, NoteTableArray, title_string);

И этонастроен в функции следующим образом ...

 int LoadNoteTableArray (Entryfile* Entryfile1, NSMutableArray* NoteTableArray,
   NSString* title_string) {

Я могу использовать объект Entryfile1 и изменять его в функции, используя различные методы объектов, и эти изменения видны в основной программе.Я могу добавить записи в NoteTableArray и посмотреть обратно в основной программе.Однако изменения в строке NSString не отражаются в основной программе.Я могу видеть title_string как @ "тестовую строку" в начале функции.Он установлен на что-то другое в функции, но это значение никогда не возвращается в основную программу.

Я смущен разницей между этими обозначениями и объектами.

Мысли?

Хорошо ... фрагменты кода ... из основной процедуры ...

checkerror = LoadConfigTableArray (Configfile1, ConfigEntryArray);
title_string = @"test string";
checkerror = LoadNoteTableArray (Entryfile1, NoteTableArray, &title_string);
[NoteTableArray sortUsingSelector:@selector(compareNoteEntryTime:)];
checkerror = RemediateNoteTableArray (NoteTableArray);
checkerror = WriteOutTimeFromNoteTableArray (NoteTableArray, ConfigEntryArray,       title_string);
[NoteTableArray sortUsingSelector:@selector(compareNoteIDandMarkTime:)];
checkerror = WriteOutNotesFromNoteTableArray (NoteTableArray, ConfigEntryArray);

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

Вы просили об этом ... выпонял ... Тойота ... вот функция ... Я не убираю расстояние для этого сайта.Часть кода была игровым кодом, так что, если вы хотите пойти дальше, это нормально, но знайте, что вы мне мало помогаете.Он читает текстовый файл (Mac или Windows), анализирует определенные строки в объектах и ​​загружает их в массив объектов.

int LoadNoteTableArray (Entryfile * Entryfile1, NSMutableArray * NoteTableArray, NSString ** title_string) {

NSString* tokenclass;
NSString* previous_tokenclass;
NSString* token;
NSString* savedheaderid;
NSString* response;
NSString* tempstring;
NSString* tempstring2;
NSString* token_xx;
NSString* entryfile1path;
NSString* entryfile1name;
NSString* responseok;
NSNumber*   temp_MarkTime;

NoteTableEntry* NoteTableEntrytemp;

char firstline;
char first_id_found;
int duplicate_count;
int arrayCount;
int loop_count;

entryfile1path = [NSString stringWithString: @"PATH"];
entryfile1name = [NSString stringWithString: @"notes"];
responseok = [Entryfile1 OpenEntryFile: entryfile1path withdatafilename: entryfile1name];
if ([responseok isEqualToString:@"ERROR"]) {return 1;};
if ([responseok isEqualToString:@"LAST"]) {return 2;};

firstline = 'N';
first_id_found = 'N';
tokenclass = nil;
*title_string = nil;

do {
    if (tokenclass == nil) {previous_tokenclass = nil;}
    if (tokenclass != nil) {previous_tokenclass = [NSMutableString stringWithString: tokenclass];}
    tokenclass = nil;
    token = [Entryfile1 GetNextToken];
    if (token == nil) {break;};

    tokenclass = [Entryfile1 ClassifyToken:token];

    if ([tokenclass isEqualToString: @"i"]) {
        [NoteTableArray addObject:[NoteTableEntry initNoteTableEntryForID:token]];
        firstline = 'Y';
        first_id_found = 'Y';
        savedheaderid = response;
        duplicate_count = 0;
        previous_tokenclass = nil;
        continue;};

    if (([tokenclass isEqualToString: @"s"]) & (first_id_found == 'N')) {
        *title_string = token;
        continue;};

    if (first_id_found == 'N') {continue;};

    if (([tokenclass isEqualToString: @"t"]) & ([previous_tokenclass isEqualToString: @"t"] == FALSE)) {
        arrayCount = [ NoteTableArray count ];
        arrayCount--;
        NoteTableEntrytemp = [NoteTableArray objectAtIndex:arrayCount];
        [NoteTableEntrytemp AddTimeEntry:savedheaderid withtimestring:token];
        continue;};

    if (([tokenclass isEqualToString: @"t"]) & ([previous_tokenclass isEqualToString: @"t"] == TRUE)) {
        duplicate_count++;
        arrayCount = [ NoteTableArray count ];
        arrayCount--;
        NoteTableEntrytemp = [NoteTableArray objectAtIndex:arrayCount];
        [NoteTableArray addObject:[NoteTableEntry initNoteTableEntryForID:[NoteTableEntrytemp NoteID]]];
        arrayCount = [ NoteTableArray count ];
        arrayCount--;
        NoteTableEntrytemp = [NoteTableArray objectAtIndex:arrayCount];
        [NoteTableEntrytemp AddTimeEntry:savedheaderid withtimestring:token];
        [NoteTableEntrytemp AddNoteType:savedheaderid withnotetype:@"t"];
        continue;};     

    if ([tokenclass isEqualToString: @"d"]) {
        arrayCount = [ NoteTableArray count ];
        arrayCount--;
        NoteTableEntrytemp = [NoteTableArray objectAtIndex:(arrayCount - duplicate_count)];
        [NoteTableEntrytemp AddNoteType:savedheaderid withnotetype:token];
        if ([token isEqualToString: @"n"] & (arrayCount > 0)) {
            NoteTableEntrytemp = [NoteTableArray objectAtIndex:(arrayCount - duplicate_count - 1)];
            temp_MarkTime = NoteTableEntrytemp.TimeMark;
            NoteTableEntrytemp = [NoteTableArray objectAtIndex:(arrayCount - duplicate_count)];
            [NoteTableEntrytemp setTimeMark: temp_MarkTime];
        }
        continue;};

    if (([tokenclass isEqualToString: @"s"]) & (firstline == 'Y')) {
        arrayCount = [ NoteTableArray count ];
        arrayCount--;
        loop_count = 0;
        do {
            NoteTableEntrytemp = [NoteTableArray objectAtIndex:(arrayCount - loop_count)];
            [NoteTableEntrytemp AddNoteHeader:savedheaderid withnoteheader:token];
            if (loop_count == duplicate_count) {
                tempstring = [NSString stringWithString: @" - XX:XX"];
                tempstring2 = [token stringByAppendingString:tempstring];
                token_xx = tempstring2;
                [NoteTableEntrytemp AddNoteBody:savedheaderid withnotebody:token_xx];}
            else {
                [NoteTableEntrytemp AddNoteBody:savedheaderid withnotebody:token];};
            loop_count++;

        } while (loop_count <= duplicate_count);
        firstline = 'N';
        continue;};

    if (([tokenclass isEqualToString: @"s"]) & (firstline == 'N')) {
        arrayCount = [ NoteTableArray count ];
        arrayCount--;
        NoteTableEntrytemp = [NoteTableArray objectAtIndex:(arrayCount - duplicate_count)];
        [NoteTableEntrytemp AddNoteBody:savedheaderid withnotebody:token];
        firstline = 'N';
        continue;};

} while (token);

return 0;

}

Ответы [ 2 ]

4 голосов
/ 03 июля 2011

Поскольку строки неизменны!

Вы не можете изменить значение строки в ее текущем месте в памяти. В вашем main program у вас есть указатель на место в памяти, в котором хранится значение "test string". В вашем методе, когда вы присваиваете новое значение title_string, вы указываете локальную переменную на новое место в памяти. Однако значение title_string в вашем main program по-прежнему указывает на исходное местоположение.

Если в вашем методе вы сказали: Entryfile1 = [[Entryfile1 alloc] init];, я думаю, вы не ожидаете, что значение EntryfileName в вашем main program изменится. Вы бы интуитивно поняли, что в вашем main application вы по-прежнему ссылаетесь на «старый» Entryfile, а не на новый, который вы только что создали. По сути, это то, что вы делаете, когда устанавливаете title_string в новое значение. Вы изменяете только указатель локальной переменной ... а не указатель, который есть в вашем main program.

EDIT: Чтобы ответить на комментарий ОП о передаче строки NSSt в массиве

Рассмотрим следующее приложение:

#import <Foundation/Foundation.h>

void foo (NSString ** stringRef);

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString * myString = @"Testing";

    NSLog(@"%@", myString);

    foo(&myString);

    NSLog(@"%@", myString);

    [pool drain];
    return 0;
}

void foo (NSString ** stringRef)
{
    *stringRef = @"Bar";
}

Результат здесь , я полагаю, это то, что вы ожидаете . И я надеюсь, что вы увидите, как это отличается от того, что вы делаете, и почему это работает (учитывая мое объяснение выше).

3 голосов
/ 03 июля 2011

Вы не можете изменить NSString с. Даже внутри метода, который вы вызываете. Они неизменны. Если вы вызываете что-то вроде stringByAppendingString: в строке, которая не изменяет строку, она возвращает новый объект NSString.

Скорее всего, вы хотите NSMutableString.

...