我有一个奇怪的问题(无论如何对我来说)。
我在我的 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 program
中 title_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/