NSMutableString *str = [[NSMutableString alloc] init];
Suppose str has right know a value "me".
And On click of a button I want that the value of str get reset. That is the string value become nil or empty.
now i am using this [myword stringWithString: #""]; but not working.
Use setString with "" as parameter.
[myWord setString:#""];
And if you want to make it nil, then release it and then set it to nil.
[myWord release];
myWord = nil;
Related
I´m doing an app and I can´t get a mutable array to accept objects. I´v tried setting breakpoints to see what´s happening but it keeps saying that the mutable array is nil. Does anyone has an answer?
My code:
- (void)save:(id) sender {
// All the values about the product
NSString *product = self.productTextField.text;
NSString *partNumber = self.partNumberTextField.text;
NSString *price = self.priceTextField.text;
NSString *quantity = self.quantityTextField.text;
NSString *weigh = self.weighTextField.text;
NSString *file = [self filePath];
//Singleton class object
Object *newObject = [[Object alloc] init];
newObject.product = product;
newObject.partNumber = partNumber;
newObject.price = price;
newObject.quantity = quantity;
newObject.weigh = weigh;
//Array declaration
mutableArray = [[NSMutableArray alloc]initWithContentsOfFile: file];
[mutableArray addObject:newObject];
[mutableArray writeToFile:file atomically:YES];
}
While initWithContentsOfFile: can be called on an NSMutableArray, it was inherited from NSArray. The return value is an NSArray which is not mutable. If you want to add objects to your mutable array, you have to do something like this:
mutableArray = [[[NSMutableArray alloc] initWithContentsOfFile: file] mutableCopy];
[mutableArray addObject:newObject];
[mutableArray writeToFile:file atomically:YES];
Now, the addObject: call should work.
Best regards.
[NSMutableArray initWithContentsOfFile:] returns nil by default if the file can't be opened or parsed. Are you sure the file you're loading exists and is formatted correctly?
Try to check with break point on
mutableArray = [[NSMutableArray alloc]initWithContentsOfFile: file];
Line. Move your cursor on mutableArray if it shows you __NSArrayI that means it is an immutable array i.e. you cant update it and if it shows you __NSArrayM that means it is a mutable array and you can update this array.
In your case you're getting immutable array thats why you cant update it.
So you have two way to get mutable Array from this file -
Method:1
mutableArray = [[[NSMutableArray alloc] initWithContentsOfFile: file] mutableCopy];
Method:2
NSArray *anyArray = [[NSArray alloc]initWithContentsOfFile: file];
mutableArray = [[NSMutableArray alloc]initWithArray:anyArray];
In both case mutableArray woud be a mutable Array. You can update it.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
NSString immutable allows to change its values?
I want to point to an object where in, if I make changes to one object. the same change has to reflect to other object. How to do that?
I have done a sample, but it is not working.
Please check the code once. What is the mistake in my code?
-(void)viewDidLoad{
str = [[NSString alloc] initWithString:#"Taruni"];
str2=str;
str2=#"Kalpana chawla";
[self changeStr:str];
NSLog(#"str = %#",str);
[str release];
[str release];
[super viewDidLoad];
}
-(void)changeStr:(NSString *)x
{
x=#"Chandra";
}
In .h file, I have declared in this way
#property(nonatomic,assign) NSString *str;
#property(nonatomic,assign) NSString *str2;
If I change the value of str2, str is not getting reflected.
How to do that?
Try below code,
-(void)viewDidLoad{
NSString *str = [[NSString alloc] initWithString:#"Taruni"];
NSString **str2 = &str;
*str2=#"Kalpana chawla";
[self changeStr:&str];
NSLog(#"str = %#",str);
[str release];
[str release];
[super viewDidLoad];
}
-(void)changeStr:(NSString **)x
{
*x=#"Chandra";
}
First of all, if you want to change the content of a string you need NSMutableString.
Second of all, in your changeStr: method you did nothing but assigned the "x" pointer to point to another string (and x is local).. In method your pointer "x" is local and assignment (x = something) will not reflect outside of that method. If you want to change something outside you will have to use x.propertyName or [x methodName]. If you want to change your input as to what string does it point to, you need input as :(NSString **)x, then *x = #"Chandra" and [self changeStr:&str].
Third of all, you can not change constant strings (defined like this: #"constant string"), you will have to use [NSString stringWithFormat:#"%#", str] (rather yet NSMutableString for your purpose)
ten.textValue = [[NSMutableString alloc]init];
ten.textValue = [NSMutableString stringWithString:textField.text];
I am getting crash at second line.
ten.textValue is NSMutableString.
It is probably because the text property of UITextField is nil by default, and passing nil to [NSMutableString stringWithString:nil] causes a crash.
You need to make sure the text is not nil when you pass it to be copied, for example like this:
[NSMutableString stringWithString: textField.text ? textField.text : #""]
You should also eliminate the first line - it serves no purpose, because the allocated and assigned value gets overwritten immediately.
When you create your ten.textValue = [[NSMutableString alloc]init]; you are creating an object that you own.
When you try to add a string to it in the next line, you are creating an autoreleased string. This is confusing the compiler, which is reporting "hang on - this is an allocated, owned object already".
Instead:
if(ten.textValue)
{
ten.textValue = [NSMutableString stringWithString: textField.text]};
}
I work on a project on iPhone iOS with Xcode 4.
With Xcode > Product >Analyze I get 35 issues, all of this type:
myTextField.text = [[NSString alloc] initWithFormat:#"0.2f", abc];
and the problem is "Potential leak of an object allocated at ..."
What is the offending object and how can I release it?
Thanks
You're leaking the string that you're assigning to myTextField.text. When this assignment happens, a copy is being made (look at the property definition in the documentation). In most cases, when values are immutable, as is the case with NSStrings, a copy will give you an instance that points to the same location as the object that is being copied, with the retain count incremented by 1.
In the case of your code:
myTextField.text = [[NSString alloc] initWithFormat:#"0.2f", abc];
The retain count of the string that you've allocated is 2.
You will either need to (1) release, (or autorelease) the string, or (2) use one of the NSString convenience methods, e.g. stringWithFormat: to create the string. This will give you an autoreleased string so you won't have to worry about explicitly releasing it.
(1)
NSString *str = [[NSString alloc] initWithFormat:#"0.2f", abc];
myTextField.text = str;
[str release]
or
myTextField.text = [[[NSString alloc] initWithFormat:#"0.2f", abc] autorelease];
(2)
myTextField.text = [NSString stringWithFormat:#"0.2f", abc]; // autoreleased
You are responsible for releasing string object you create here - as you use alloc/init for that.
The most convenient way here to set a string is to use class method +stringWithFormat that returns autoreleased string - so system will release that string object for you later:
myTextField.text = [NSString stringWithFormat:#"0.2f", abc];
Or you can write autorelease explicitly if you want:
myTextField.text = [[[NSString alloc] initWithFormat:#"0.2f", abc] autorelease];
If you don't want to use autorelease you can use temporary variable to create new string and release it after it was set for text field:
NSString *tempString = [[NSString alloc] initWithFormat:#"0.2f", abc];
myTextField.text = tempString;
[tempString release];
The thing is that UiTextFields's text property is declared as:
#property(nonatomic, copy) NSString *text
Therefore in this line:
myTextField.text = [[NSString alloc] initWithFormat:#"0.2f", abc];
A new NSString is created with a retain count of 1, and then myTextField.text copies this object and increased its retain count by 1 or does it??, lets see what is happening:
A NSString object created with alloc initWithFormat with a retain count of 1
A NSString object with is a copy of the previous String, but because NStrings are immutable in this case, copy returns the same object!, therefore the NSString actually has a retain count of 2.
I am receiving this error: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
In the ViewDidLoad I initialized my array:
id object = [[NSUserDefaults standardUserDefaults] objectForKey:#"array"];
if (object)
{
locationArray = object;
NSLog(#"retrieved", object);
}
else
{
locationArray = [[NSMutableArray alloc] init];
NSLog(#"init");
}
Then, I am trying to add the data to locationArray:
ABMultiValueRef multi = ABRecordCopyValue(person, property);
NSUserDefaults *locatie = [NSUserDefaults standardUserDefaults];
// Set up an NSArray and copy the values in.
NSArray *theArray = [(id)ABMultiValueCopyArrayOfAllValues(multi) autorelease];
//everything goes fine the first time, but the second time i receive an error after at this code:
[locationArray addObject:theArray];
[locatie setObject:locationArray forKey:#"array"];
Every first time I select an address everything is fine. But every second time I am receiving that error.
What did I do wrong?
NSString *fname = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSMutableString *lname = (NSMutableString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
What makes you think ABRecordCopyValue is going to return a mutable string here?
Just telling the compiler that it will return a mutable string (which is all “(NSMutableString *)” does) doesn't mean it will. If the Address Book documentation doesn't specify that this will return a mutable string, assume it won't and create a mutable string yourself.
Speaking of which…
NSMutableString *name = [[NSMutableString alloc] init];
Here's the string you should be appending to. You don't need lname to be mutable, because this string is mutable.
NSMutableString *space = #" ";
fname = [fname stringByAppendingFormat:space];
fname = [fname stringByAppendingFormat:lname];
By doing this, you waste the mutable string you created. You are creating two intermediate immutable strings here, not appending to the mutable string.
name = fname;
And here, you throw away the mutable string entirely (and thereby leak it since you never released it), replacing it with the immutable string you got from your series of stringByAppendingFormat: messages.
What you should do is send the name mutable string an appendFormat: message, passing both the first and last name strings. You don't need the space string; you can include that in the format string.
See also the NSMutableString docs.
[nameArray addObject:fname];
At no point prior to this statement have you created an NSMutableArray object and stored its pointer in the nameArray variable. Not in any code you've shown, anyway.
Until you do that, this variable holds nil, the pointer to no object. The addObject: message does nothing because that's what messages to nil do: Nothing. Logging the array you don't have produces “(null)” because that's the description of nil.
if (nameArray == nil) {
NSLog(#"NO DATA TO RETRIEVE FROM USERDEFAULTS");
You aren't showing any code that retrieves from user defaults. Even if you did, it would return an immutable array as Sven said; you would have to make a mutable copy.
This is the best I can do without a description of the problem. We may be able to provide more and better suggestions if you edit your question to tell us what happens when you run the above code, and not just what doesn't happen.
The problem occures when you get the locationArray from the NSUserDefaults and try to insert some object ([locationArray addObject:theArray];). The object you get from the NSUserDefaults is not mutable, so you have to create a mutable copy:
NSMutableArray* locationArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"array"];
if (locationArray != nil)
locationArray = [[locationArray mutableCopy] autorelease];
else
locationArray = [NSMutableArray array];
And don't forget to check if fname is not nil before adding it to array