Objective-c 和使用 NSString 作为函数参数

标签 objective-c function pass-by-reference

我有一个奇怪的问题(无论如何对我来说)。

我在我的 Objective-C 程序中调用一个函数并传入三个参数...一个自制对象、一个 NSMutableArray 和一个 NSString。

函数原型(prototype)看起来像这样....

 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 的更改不会反射(reflect)在主程序中。我能够在函数的开头将 title_string 视为 @"test 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);

请注意,在我解决这个问题后,check error 将用于捕获各种函数报告的错误情况......

您要求它...您得到它...丰田...这是功能...我不会清理此发布站点的间距。一些代码是播放代码,所以如果你想继续使用它也没关系,但请注意你对我的帮助不大。它读取文本文件(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;

最佳答案

因为字符串是不可变的!

您不能更改字符串在内存中当前位置的值。在您的主程序中,您有一个指向内存中存储值"test string" 的位置的指针。在您的方法中,当您为 title_string 分配一个新值时,您将局部变量指向内存中的一个新位置。但是,main programtitle_string 的值仍然指向原始位置。

如果在您的方法中,您说:Entryfile1 = [[Entryfile1 alloc] init];,我猜您不会期望 EntryfileName 在您的main program 中更改。您会直观地了解到,在您的 主应用程序 中,您仍在引用“旧的”Entryfile - 而不是您刚刚创建的新文件。当您将 title_string 设置为新值时,这实际上就是您正在做的事情。您只是在更改局部变量的指针……而不是您在 main program 中的指针。

编辑: 解决 OP 关于在数组中传递 NSString 的评论

考虑以下应用:

#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";
}

这里的结果,我相信,就是您期待的结果。我希望您会看到这与您正在做的事情有何不同,以及为什么这样做有效(根据我上面的解释)。

关于Objective-c 和使用 NSString 作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6560459/

相关文章:

ios - UISegmentedControl 分隔符错误

ios - 模拟器上的 Xcode 应用程序在真实设备上崩溃

ios - 如何在升级后的应用程序中检索 NSUserDefault 值?

java - 如何从类内部的函数中获取值?

c++ - 如何在 C++ 中创建只读取一次的初始化函数

c# - 为什么我的 INT 变量是通过引用传递的? C#

ios - 了解后台任务执行语法和 GCD

c++ - 以对象为参数的函数,作为另一个函数的参数

java : Best way to pass int by reference

C++ 引用 - SomeType* &val 与 SomeType* val