Iphone TextField.text - iphone

i have this code in my app where i put the text field text in my NSString property.
iname = textField.text;
after that at some point im doing this to make sure that the string is not empty
[iname isEqualToString:#""]
the problem is that if the textfield contain one word without space it works great
if there is space it crashes! and i cant understand why ?
please help! thank you so much

iname = textField.text;
iname is an instance variable, right? If so, you need to take co-ownership of this string, so that the string doesn't die when the text field stops owning it (which will happen if anything, including the user, replaces the text field's value for text with a new value—a new string). Simply assigning the string's pointer to one of your instance variables does not take ownership of the string. See the Memory Management Programming Guide for Cocoa Touch for more information.
If you don't do that, then your program will crash when you try to send a message to the now-dead object whose pointer you have in iname.
after that at some point im doing this to make sure that the string is not empty
[iname isEqualToString:#""]
…for example.
the problem is that if the textfield contain one word without space it works great if there is space it crashes!
Sometimes there can be an element of randomness to whether the crash manifests.
The way to prove my theory would be to run your app under Instruments's Zombies instrument. That instrument causes objects with no owners to not die (be deallocated), but instead become zombies. When you send a message to a zombie, you'll get a flag in the Instruments timeline, which you can use to examine the object and its history to find out why it died before it should have/why you're still holding onto it after it died.

Using the getter properly solve the problem
self.iname = textField.text;

Related

Setting an objectAtKey string from NSDictionary to an NSString in separate class

I have got information from a URL(JSON); I easily populate my tableView with the text from my dictionary [aCategory objectAtKey:#"names"] for the cell labels. Now, based on the cell name (category), I want to display another table that will ask for the last URL in order to grab the rest of the text, based on that category.
So, i want an ID which is in [aCategory objectAtKey:#"ID"] to save to a string and put in the URL in the next viewController. I am currently trying to generate it using the auto-generated set method to populate the NSString *ID in the target viewcontroller; when i call
[newView setID: [aCategory objectAtKey:#"ID"].
My new view controller's NSString ID says it is not empty, but when i try to check to see if it is indeed "1" or "2" i get something like /p2002 or something. However, in the original class, if i say cell.detailLabelText.text = [aCategory objectAtKey:#"ID"];, the labels correctly show "1" "2" "3".."14" etc....
SO, how can i get that ID from that key into my other viewcontroller class?
I Know it is a valid NSCFString cause i tested it both with isClass AND with the cell's detailLabelText.
I need more detail to be sure about this, but a couple of notes...
NSString is what is called a class cluster, which basically means it is actually a collection of several class different classes that the underlying framework switches between...this means if you are checking it with
isKindOfClass:
you might not be getting the results you are expecting. Check the documentation for isKindOfClass: in NSObject.
However, I am not sure if there is anything to worry about. The reason you are seeing something like '\p2002' (Could the first letter be a u?) could just be the current underlying representation of the string. Sometimes, when the device holds the content of the string in memory, it does not look exactly like "1" or "2". It doesn't mean that there is a problem: it just means that, a deeper level, the way the string is being held in memory is in different form. That is why your label might say "2" but the variable, when you check it in memory, looks different.
(I am guessing that, since you are handling JSON, the string is encoded in a form called UTF-8.) The point is, nothing may wrong at all.
The real question is, is your new view controller loading correctly or not? Maybe in the viewDidLoad: method of your new view controller, if you run something this line:
NSLog(#"%#", stringID);
This will print the value of stringID to the console. If this number is the same as the number of the table cell's label in the previous view controller, everything should have been passed correctly.

attempt to mutate immutable object randomly thrown

One part of the program takes text from a uitextfield, copies it to a mutable string and then performs
sharedManager.ce_name=name.text
[sharedManager.ce_name replaceOccurrencesOfString:#" " withString:#"%20"
options:NSLiteralSearch range:NSMakeRange(0, [sharedManager.ce_name length])];
At this point it always gave me "attempt to mutate immutable object" - it was not random
The first time I got this error I changed it to
sharedManager.ce_name=(NSMutableString *)name.text
This STILL gave me the attempt to mutate immutable object error, but it would occur randomly - weird right?
I then changed it to
NSMutableString *mutable_name = [NSMutableString stringWithString:name.text];
sharedManager.ce_name=mutable_name;
It has yet to fail on me doing it this way but I am convinced that I have not found the solution.
my questions:
1) Could that fact that it was doing it randomly after the first fix indicate I have some deep seated memory management problem?
2) Why didn't the C-style cast fix it?
3) Will my current fix work?
Thanks for your time :)
The problem here is the way in which you're using casting. When you cast a pointer, it just starts treating the memory at that location as though it were a block of data representing that type.
So if I've got a pointer to a Car class: Car* mycar;, and I cast it to a Person object: (Person*)mycar;, the program will try to access the memory there as though it was pointing at a Person object. However, a car is not a person, except in an old TV sitcom, so when it tries to access members on this or call functions, it's going to try to go to a memory location that contains something other than what it's expecting, and undefined things happen (generally, crashing).
NSMutableString and NSString are incompatible in this regard, and so casting from one to the other will result in terrible times. Your fix ([NSMutableString stringWithString:]) is the correct solution.
If it was doing it randomly, it means that name.text was sometimes a mutable string and some times an immutable string.
Casting between objects like that doesn't change the class of the object. It won't make your immutable object mutable.
That "fix" is probably the best way to do it (at least from what I can see in the code you are showing)
Without seeing at least the declarations of the variables involved, it's difficult to say for certain, but your final solution, creating a new mutable string is likely the correct fix. As for your questions,
Not memory management per se, but it was probably overwriting something it shouldn't have somewhere.
Casts cannot change the fundamental type of an object. You had (presumably) an NSString and all the casting in the world cannot make it into an NSMutableString.
Like I said, probably, but we'd need to see more code to make sure. It's certainly a much better fix.

Nsstring objects changing its data type

I have a certain nsstring property declared in a variable, it is used to do store a text string when i am performing a parsing operation. As this parsing operation happens mulitple times, the Nsstring property changes bizzardly to any random data type and crashing my application. This happens when i try to compare the property with other local variable which is also string. But by the time i compare, the appdelegate variable has already changed its data type, and hence crashes my app.
Any one ever come across such issue? If so, please guide me.
It is a sign that your NSString object has been deallocated so you send a message to a deallocated object. That crashes your application. The datatype changes because after an object is deallocated the memory it was placed in is not correct anymore and may contain a trash. You should use Run with Performance tool -> Leaks tool. It helps a lot in such cases. Please keep in mind that you should enable zombie object detection in settings.

iPhone leak on this line, why?

I am getting a leak on this line and I'm not sure why...
weather.condition = [weather.condition lowercaseString];
weather is a NSMutableArray with a load of NSStrings in? Is there anything obviously wrong with this line or is it a bigger issue?
Thanks
One thing you have to learn about detecting memory leaks, is that leaks doesn't detect the line the leak occurs on per say, it detects where the object that is leaking was retained/copied/created. You need to look elsewhere for the actual leak, posting more code would be helpful. I'll update this answer if you do. Please comment below to indicate you've updated the answer with more code.
I remember i had this problem when i was using stringByReplacingOccurrencesOfString and i had to declare a new string to hold it in, rather than perform it on itself if that makes any sense!:)
If weather.condition is a synthesized retain property, then you could probably get away with that statement without a leak because the synthesized setCondition method will check to see if there is a value assigned to condition, and release it. If you wrote the setCondition method, you are responsible for managing the memory associated with condition.

A Simple Objective C xcode Memory Management Question

In the code below, will tapsLable.text be deallocated when tapsMessage is released or does the assignment operator somehow increment the retain count so that tapsLabel.text continues to be available?
NSString *tapsMessage = [[NSString alloc] initWithFormat:#"%d taps detected", numTaps];
tapsLabel.text = tapsMessage; // tapsLabel is a UILabel object
[tapsMessage release];
Here's a tip
You can write the retainCounter for the object then you see what it is before and after the assignment.
e.g. NSLog( #"%d", [tapsMessage retainCount] );
That way you can answer such questions in the future by just writing out the retainCount as it always depends on how the property is declared.
tabsLabel.text is a property on tapsLabel. I think it's a string property that does [target copy] on assignment. Nevermind the details, yes, the assignment operator either increments the retain count or copies the value, so you can release tapsMessage and it is still available in tapsLabel.text.
Read more about properties here.
EDIT: looked up UILabel in the header, yes, it does a copy for the text property.
#property(nonatomic,copy) NSString *text; // default is nil
EDIT: to expand on the important question in the comment
How does anyone know when to release and when not to if you have to look at the implementation details of every object you assign something to?
You just follow the memory management rules. The point of the refcounted environment is exactly that there is some "loose coupling" going on between the objects in terms of memory management. As long as you retain and release properly, it is not your concern whether someone else also retains and releases these same objects, as long as all involved parties have their retains/releases matched.
In the first line, you have allocated and initialised an NSString. You own this object according to the memory management rules, which means you are responsible for releasing it.
In the second line, you are assigning the tapsMessage string the text property. This property (assuming tapsLabel is a UILabel) is declared with the copy attribute. For immutable strings (NSStrings), asking for a copy simply increments the retain count, since there is no need to make an actual duplicate of the data (the data can never change). Since UILabel has made a copy of the string, it has claimed ownership as well (objects can have more than one owner).
In the third line, you relinquish your ownership but the string still has one owner (the label), so the object is not deallocated.
It will not be deallocated.