Why does my NSString becomes CGPath? Xcode, Titanium - objective-c

So the short of it is I want to define a global string variable that I can reference whenever. The function that I reference it in, it returns a string. As soon as I store it and reference it in another function it outputs as <CGPath 0x5bbf50>
What the heck? The code is below and keep in mind this is a module for Titanium.
First, the definition of the global variable..
#interface ComTestModule : TiModule <CBCentralManagerDelegate, CBPeripheralDelegate>
{
NSString * teststring;
}
The next part is the function where I first send the string variable from titanium to xcode..
-(void)setService:(id)args{
ENSURE_ARG_COUNT(args, 2);
teststring = [args objectAtIndex:0];
NSLog(teststring);
}
The output of the NSLog displays the actual string that was passed.
Now the final function where I call the string again and attempt to output it to the log..
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
NSLog(#"---%#", teststring);
}
As I said before, during this step it outputs as ---<CGPath 0x3ef4e0>
I'm really not sure what's going on.. Any help at all about getting this to return as the original string instead of the CGPath would be great!

Effects like this typically happen when you store a pointer to an object that was released and deallocated. The runtime will then replace that chunk of memory that previously held an NSString instance with, in this particular case, a CGPath instance.
If you want to ensure that your NSString stays alive, you need to take ownership of it. You can do that by either retaining it or copying it. Copying is the preferred method when talking about strings, so try replacing this line:
teststring = [args objectAtIndex:0];
With this:
teststring = [[args objectAtIndex:0] copy];
Now just be sure to release it when you're done.

The other poster's suggestion was good. You might want to make your testString variable into a copied property:
In your .h file:
#property (nonatomic, copy) NSString teststring;
And in your .m file
#synthesize teststring;
Then when you assign to it, use code like this:
self.teststring = [args objectAtIndex:0];
That "dot syntax" invokes the setter for your property rather than changing the instance variable directly. Since you declared your property with the "copy" qualifier, the setter method copies the string before putting it into the instance var.
Finally, you would add this code to your dealloc method:
self.teststring = nil;
The setter method also releases any old value in the property before assigning a new value, so setting it to nil releases the old value.

Related

AFNetworking: is it safe to access variable outside block?

I'm trying to debug an issue when storing variable outside a block.
- (void) setObj : (NSString *) abc {
[self postURL:#"..." params:#{"abc" : abc} completionHandler:^(id response) {
[[SharedPref sharedInstance] setX:response];
[[SharedPref sharedInstance] setAbc:abc]; <-- can we safely do this?
} failureHandler:^(SBError *error) {
}];
}
I've seen cases where when in later time I try to access abc, I'm getting empty string.
[[SharedPref sharedInstance] getAbc]; <-- this return empty string
It should be safe as long as the abc property in SharedPref is strong or copy. For NSString* types, it's preferred to use copy.
#interface SharedPref : NSObject
#property (copy,nonatomic) NSString* abc;
#end
The difference is as follows:
strong:
strong indicates that the class owns the property
strong increases the reference count of the property by 1
instance will not be released until its reference count is 0.
copy
copy assigns a shallow copy when assigning the property by calling [copy]
copy ensures that you're always dealing with an immutable property. If a mutable property is passed in, it will copy it. If a immutable property is passed in, it will retain it (you would need to dealloc it).
There is nothing wrong with what you are doing. The local variable abc (which is a pointer to an object) is captured by the block and abc inside the block will be a pointer to the same object. Assuming it's an immutable string or you never mutate the string, it should be the same string that is passed to setAbc:.
Given that postURL: is an asynchronous operation (i.e. the completion block is called at some undetermined later time), I am suspecting that you are making false assumptions about the ordering of operations. The completion block that does setAbc: might not have been called yet by the time you do getAbc, and so what you get is the initial value before you set it.

NSString allocation and initializing

What is the difference between:
NSString *string1 = #"This is string 1.";
and
NSString *string2 = [[NSString alloc]initWithString:#"This is string 2.];
Why am I not allocating and initializing the first string, yet it still works? I thought I was supposed to allocate NSString since it is an object?
In Cocoa Touch,
-(IBAction) clicked: (id)sender{
NSString *titleOfButton = [sender titleForState:UIControlStateNormal];
NSString *newLabelText = [[NSString alloc]initWithFormat:#"%#", titleOfButton];
labelsText.text=newLabelText;
[newLabelText release];
}
Why do I not allocate and initialize for the titleOfButton string? Does the method I call do that for me?
Also, I'm using XCode 4, but I dislike iOS 5, and such, so I do not use ARC if that matters. Please don't say I should, I am just here to find out why this is so. Thanks!
The variable string1 is an NSString string literal. The compiler allocates space for it in your executable file. It is loaded into memory and initialized when your program is run. It lives as long as the app runs. You don't need to retain or release it.
The lifespan of variable string2 is as long as you dictate, up to the point when you release its last reference. You allocate space for it, so you're responsible for cleaning up after it.
The lifespan of variable titleOfButton is the life of the method -clicked:. That's because the method -titleForState: returns an autorelease-d NSString. That string will be released automatically, once you leave the scope of the method.
You don't need to create newLabelText. That step is redundant and messy. Simply set the labelsText.text property to titleOfButton:
labelsText.text = titleOfButton;
Why use properties? Because setting this retain property will increase the reference count of titleOfButton by one (that's why it's called a retain property), and so the string that is pointed to by titleOfButton will live past the end of -clicked:.
Another way to think about the use of retain in this example is that labelsText.text is "taking ownership" of the string pointed to by titleOfButton. That string will now last as long as labelsText lives (unless some other variable also takes ownership of the string).

alloc and release problems

I can't figure out why my app is crashing after a few times I'm doing:
potionsT is nonatomic, retain, readonly.
-(void)First:(NSString*)Potions {
potionsT = [[NSString alloc] initWithString:Potions];
}
-(void)After:(NSString*)Potions {
[potionsT release];
potionsT = [[NSString alloc] initWithString:Potions];
You see, I'm first calling First and after that I'm calling a few times After: and wopes, it crashes. with ECX_BAD_ACCESS.. I'm pretty noob with all that memory manage thing, I know that... Thanks!
The point of retained property is it handles retain and release when you set it.
- (void)first:(NSString*)potions
{
self.potionsT = potions; // will automatically release old value and retain new
}
- (void)after:(NSString*)potions
{
self.potionsT = potions; // same as above
}
Also note how i renamed your Potions to potions, First: to first:, and After: to after:. Objective-C naming convention is to start variables and methods with lowercase letter, and class names with capital.
Did you #synthesize the property in the #implementation for the class? If so, then you should use:
self.potionsT = Potions;
if you use
potionsT = ...
then you are accessing the ivar, not the property. To access the property and let it do the memory management for you, you must precede it with an instance reference, and that can also be self.
If you use the property, you should not release potionsT manually, since the property already does that for you.
If you've set up potionsT as a property, you should access it that way:
-(void)first:(NSString*)potions {
self.potionsT = potions;
}
-(void)after:(NSString*)potions {
self.potionsT = potions;
}
In both cases, I changed your code to use the accessor for potionsT (that's what the self.potionsT means). I'm also not creating a new string, but just retaining the provided one. Since NSStrings are immutable, the result is the same. For best results, though, change the potionT property from retain to copy. That way, if a mutable string gets passed in, it'll be copied instead of retained (and immutable strings will still just be retained).

objective-C: simple question about copy/retain NSString

If I set a NSString as property
#property (copy) NSString* name;
I always want to use (copy), so that if its value change, all object with such string still have the old value (as specifiedhere).
However, what happens if my NSString is not a class property, but it is just declared in the code ? Is in that case retained or copied everytime I assign a new value ?
thanks
It depends on how you declare it. You should read the documentation on memory management. Basically the rules are:
NSString *aString = [NSString stringWithString:#"Hello"];
NSString *bString = [NSString stringWithFormat:#"%#", #"Hello"];
In these cases, the string is not copied or retained. It is autoreleased, which means it will be automatically deallocated the next time the autorelease pool drains. You do not have to call the release method on them. (So assigning a new value will not cause it to leak.)
NSString *cString = [[NSString alloc] initWithFormat:#"%#", #"Hello"];
[cString release];
According to Objective C convention, methods that use alloc and have a retain count of one are not autoreleased, so you need to release them explicitly. Assigning a new value without releasing the old one will cause a leak.
You can also explicitly call a "copy" method or a "retain" method on a string. In either case, the new string will have a retain count of 1 and will not be autoreleased, so you will need to call the release method on it before you assign a new value.
NSString *dString = [cString retain];
NSString *eString = [cString copy];
...
[dString release];
[eString release];
If it is a property, and you use self.variableName, this will be taken care of for you (through the getters and setters which are generated with #synthesize). If you do it explicitly, you must make sure to call release on variables that you have called retain or copy on.
Edit: As some commentators below have noted, thinking about management in terms of "ownership" is usually the preferred of describing these ideas, rather than retain count.
If it's not a property and just declared in code, you need to explicitly retain or copy it, ie
NSString myString = [otherString copy];
or
NSString myString = [otherString retain];
Either way you also need to ensure it's released at somepoint.
If you're not using the property's setter, like self.name = #"foo" or [self setName:#"foo"], but rather assign the variable directly, like name = #"foo", it doesn't matter at all how the property is declared.
You have to understand that the property syntax is just a shortcut for writing accessor methods (-name and -setName: in this case). If you're not calling these methods (implicitly by setting the property), it doesn't matter how they work internally (which is what you specify by retain or copy).

Difference bewteen declaring a NSString with alloc and init and assigning with #"myString"

Currently I'm troubled with a small understanding issue on Objective-C. As example following Aaron Hillegass's book, I'm wondering about assigning an NSString in the init method of a class a value like in this example (For people who know the book, this is used in the Person class of RaiseMan):
- (id)init
{
if(![super init])
return nil;
myString = #"New entry";
return self;
}
This string isn't allocated by me, so normally I shouldn't bother about releasing it.
BUT! What happens in a setter-method of this string? Following the memory management rules the method should look like:
- (void)setMyString:(NSString *)newString
{
if(myString != newString) {
[myString release];
[newString retain];
myString = newString;
}
}
Why does [myString release] work? I've read somewhere, that with = #"bla" assigned strings can't be released.
And is initializing with = #"bla" the right way? Or should I use alloc and init instead?
Thanks for any help :)
NSString *constantString = #"constantString";
String like constantString are said to be from a private(?) class NSConstantString and they are alive through all your program life. Off-course release and retain work, (in the mean that they won't give you a exception or crash) They just do nothing.
Read more here
Also you said in one of your comments that it would be a{#property(..., copy) NSString myString;But what you are showing us is a typical #property(..., retain)
AFAIK, string constants of the form #"..." are actually a child class of NSString that redefine retain and release as no-ops. This allows the compiler to store those string constants in the data segment of your executable instead of on the heap.
Is myString declared in the header-file? Like: #property(nonatomic, retain) NSString myString. If that is the case, then myString is retained. Otherwise, it's not necessary to release it.