Why is substringFromIndex not working for my NSMutableString ?
Here code similar to what I have :
NSMutableString *myString = [[NSMutableString alloc] initWithString:#"This is my String"];
[myString substringFromIndex:5];
NSLog(#"myString = %#", myString); //will output This is my String
If I use substringFromIndex on NSString it will work, for example like so :
NSString *tempStr = [[NSString alloc] init];
tempStr = [myString substringFromIndex:5];
NSLog(#"tempStr = %#", tempStr); //will output is my String
Why does it not work in the first example, and I have one more question, if I do it using the second method, and then I set:
[myString setString:tempStr];
[tempStr release];
This will result in a crash, I thought, since I used setString on NSMutableString, that I do not need the NSString and I release it, but apparently that is not the case, however if I use autorelease it will be OK
That method never alters the string you call it on. It returns a new string in both cases. So assign it to a new string variable and your good.
It's crashing because you over releasing one object and and leaking another. You alloc the first string, then make a new autoreleased string from substringFromIndex:, then release it. You dont need to try this hard.
Simply assign the output of the substring method to a variable, and let it be autoreleased for you. No alloc, no release.
A full proper example might look like this:
NSMutableString *myString = [[NSMutableString alloc] initWithString:#"This is my String"];
NSString *tmpString = [myString substringFromIndex:5];
NSLog(#"tempStr = %#", tempString);
[myString setString:tempStr];
// later do [myString release]
or even simpler:
NSString *myString = #"This is my String";
myString = [myString substringFromIndex:5];
You create an NSMutableString specifically so you CAN modify it.
But no one knows any way to do this:
[myMutableString substringFromIndex:5];
And if you are going to do this instead:
myMutableString = [myMutableString substringFromIndex:5];
why even use a mutable in the first place.
MutableStrings are great for ADDING (appending) to them.
Not sure why we can't also shorten (substring) them. (Without making a new copy.)
[myString substringFromIndex:5] returns a new NSString that starts from the specified index. It does not modify myString.
try this code instead:
NSLog(#"myString = %#", [myString substringFromIndex:5]);
Related
I am dividing string and and storing it in splitArray and want to return it.
But I am getting conflicting array on the first line
- (NSArray *)subdividingString:(NSString *)string {
NSArray *splitArray = [string componentsSeparatedByString:#" "];
return splitArray;
}
First: there is nothing wrong with the code, but you are most likely having another issue (e.g. where you call subdividingString:).
Second: You shouldn't introduce a method that is exactly doing what another one is doing already. Just use
NSString *mystring = #"some string";
NSArray *chunks = [mystring componentsSeparatedByString:#" "];
I want to add multiple NSStrings yo an NSMutableString to construct a list of strings.
This is my code in a method that takes an NSDictionary and grabs the value out of it - it then stores it in an NSString, From there I append the string to the NSMutableString. When running this method for the first time it works. However, when I call the method again, it replaces the last string that was in the NSMutableString.
Here is the code:
NSString *userId = [NSString stringWithFormat:#"%#,", parameters[#"userId"]];
self.alluserIds = [NSMutableString string];
[self.alluserIds appendString:userId];
Can anyone tell me what I am doing wrong?
self.alluserIds is declared strong.
This:
self.alluserIds = [NSMutableString string];
is creating a new mutable string. It should be done once, before you want to use the mutable string, and not done again until you want to restart (because recreating the mutable string destroys the old instance you had).
This is happened because you call:
self.alluserIds = [NSMutableString string];
This create new string and assign it to self.alluserIds. You should call it just once in for example init method or viewDidLoad.
You should initialize with the string you are using and it should be a single initialization your code should look like below.
NSString *userId = [NSString stringWithFormat:#"%#,", parameters[#"userId"]];
if(!self.alluseIds)
self.alluserIds = [[NSMutableString alloc] initWithString:userId]; //ONLY Initialization
else
[self.alluserIds appendString:userId];
Hope this helps
I don't know your data-structure, but if you might have all userids in an array you could join them together with componentsJoinedByString::
NSArray *pathArray = [NSArray arrayWithObjects:#"here", #"be", #"dragons", nil];
NSLog(#"%#",[pathArray componentsJoinedByString:#" "]);
Don't use mutable strings(and mutable collections too) except cases you really need it: http://rypress.com/tutorials/objective-c/data-types/nsstring.html (When To Use Mutable Strings) You have to use them when you want to make a lot of operations. Immutable collections are slower because you create new instance when append another string.
How to do this with NSString:
self.alluserIds = [self.alluserIds stringByAppendingString: userId];
I have the following three lines of code in my program:
NSMutableString *stringOne = [NSMutableString stringWithFormat:#"Hello "];
NSMutableString *stringTwo = [NSMutableString stringWithFormat:#"World"];
NSMutableString *sayIt = [stringOne stringByAppendingString:stringTwo];
Despite the fact that it works, the third line is causing the warning Assigning NSMutableString * from NSString *.
I am at a loss here since everything I am using is an NSMutableString.
Not quite. stringByAppendingString does not return an NSMutableString. Instead do the following:
NSMutableString *sayIt = [NSMutableString stringWithString:stringOne];
[sayIt appendString:stringTwo];
Or
NSMutableString *sayIt = [[stringOne stringByAppendingString:stringTwo] mutableCopy];
I just realized that stringByAppendingString: returns an NSString despite calling it from an NSMutableString object. Since I am dealing with NSMutableString, I should have used that class's appendString: method. The new code that works without a warning is:
NSMutableString *stringOne = [NSMutableString stringWithFormat:#"Hello "];
NSMutableString *stringTwo = [NSMutableString stringWithFormat:#"World"];
[stringOne appendString:stringTwo];
Will this bit of code produce any memory leaks? Is it the correct way to change NSString values?
NSString * enemiesAndElementsTextureFileName = #"bla bla";
enemiesAndElementsTextureFileName = #"bl";
That way of doing it won't cause any memory leaks and it is indeed correct. In this case you wouldn't need an NSMutableString because you aren't altering the string literal itself, you are simply replacing the string value with a new one (replacing #"bla bla" with #"bl").
In this case, however, your string will now be 'bl', so you can delete that first line value and just have NSString * enemiesAndElementsTextureFileName = #"bl";
Yes NSString allocated once. This is one of the way
Yes, use NSMutableString with the following method as your needs:
// Allocate
NSMutableString *str = [[NSMutableString alloc] initWithCapacity:10];
// set string content
[str setString:#"1234"];
// Append
[str appendString:#"567"];
// Concat
[str appendFormat:#"age is %i and height is %.2f", 27, 1.55f];
// Replace
NSRange range = [str rangeOfString:#"height"];//查找字符串height的位置
[str replaceCharactersInRange:range withString:#"no"];
// Insert
[str insertString:#"abc" atIndex:2];
// Delete
range = [str rangeOfString:#"age"];
[str deleteCharactersInRange:range];
NSLog(#"%#", str);
In my app, I have a view where user have to fill a form. But, sometime the app crash here, in this function, that simple cacth the value field and built a url to give
-(NSString*)urlToUpload{
NSString *string1 =[[NSString alloc]init];
string1= [NSString stringWithFormat:#"?nombre="];
NSString *string2 = [string1 stringByAppendingString:nameAdded];
//crash here
NSString *string3 = [string2 stringByAppendingString:#"&horario="];
NSString *string4 = [string3 stringByAppendingString:horarioAdded];
NSString *string5 = [string4 stringByAppendingString:#"&info="];
NSString *string6 = [string5 stringByAppendingString:infoAdded];
NSString *string7 = [string6 stringByAppendingString:#"&offerta="];
NSString *string8 = [string7 stringByAppendingString:offertaAdded];
NSString *lat_string = [[[NSString alloc] initWithFormat:#"%f",locationToUpload2.latitude] autorelease];
NSString *lon_string = [[[NSString alloc] initWithFormat:#"%f",locationToUpload2.longitude] autorelease];
NSString *string9 = [string8 stringByAppendingString:#"&latitude="];
NSString *string10 = [string9 stringByAppendingString:lat_string];
NSString *string11 = [string10 stringByAppendingString:#"&longitude="];
NSString *string12 = [string11 stringByAppendingString:lon_string];
NSString *url1 = [NSString stringWithFormat:#"http://myserverside/mysql_up.php"];
NSString *url = [url1 stringByAppendingString:string12];
return url;
}
EDIT:
It seems problem appers on nameAdded when there is a white space into textField(i.e. MisterB not crash, Mister B yes ).
But I am using:
nameAdded =[[nameField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
and NSLOg give of nameAdded is Mister%20B.
The crash still appearing...
Just use a single stringWithFormat::
- (NSString *)urlToUpload {
NSString *url = [NSString stringWithFormat:#"http://myserverside/mysql_up.php?nombre=%#&horario=%#&info=%#&offerta=%#&latitude=%f&longitude=%f",
[nameAdded stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[horarioAdded stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[infoAdded stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[offertaAdded stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
locationToUpload2.latitude, locationToUpload2.longitude];
return url;
}
Make sure the referenced variables are valid.
In your original code there is no need to alloc/init an NSString then assign another string to the same variable. That's a memory leak (string1).
If you really want to structure your code the way you have it, at least use an NSMutableString and append to that one mutable string. Creating over a dozen NSString variables is the wrong way to do it.
Updated: Ensure each of the strings added to the URL are properly escaped.
It looks like nameAdded may be the cause of your problems. Is it nil at that point?
Also
You are allocating a string, setting it to string1 and then immediately setting string1 to the class function stringWithFormat which allocates another string. Also you are using stringWithFormat but you aren't using any format so you could simply use NSString *string1 = #"?nombre=";
Rather than declaring all of those variables you should just use NSMutableString and build it all in one variabl