Trouble appendingStrings (NSString) within a method? - iphone

when i am using string concatenation in method(like -(IBAction)buttonDigitPressed:(id)sender) it shows the blank.I am recall the method automatically terminate the app. what is the problem plz replay me.
NSString *str= #"";
-(IBAction)buttonDigitPressed:(id)sender{
int a = (int)[sender tag];
str= [str stringByAppendingFormat:#"%i",a];
label1.text= str;
}
this is the code. check the code send me the replay where i am doing the mistake.

str in the method is an autoreleased object. Make it a copy property and do
self.str = [self.str stringByAppendingFormat:#"%i",a];
label1.text = self.str;
If str is same as label1.text then do this directly.
label1.text = [label1.text stringByAppendingFormat:#"%i",a];

Related

iOS Beginner: String concatenation

I've concatenated string using the following code:
NSString *add = #"a ";
lbl.text = [add stringByAppendingString:lbl.text];
Which adds 'a ' to lbl variable every time I call the function.
But for some reason this method concatenates in a way that the new string adds in the beginning of what's already there, and not to the end.
Instead of getting AAABBB, I get BBBAAA. How do I fix this?
If a = AAA and b = BBB then you will need to write
[a stringByAppendingString:b];
So in your case it will be
[lbl.text stringByAppendingString:add]; as lbl.text = AAA and add = BBB.
For more information about this method please see NSString documentation.
NSMutableString *aString = [NSMutableString stringWithString:#"AAA"];
NSMutableString *bString = [NSMutableString stringWithString:#"BBB"];
[aString appendString:bString];
NSLog(#"Astring:%#",aString);
You can also use NSMutableString. Declare an NSMutableString *s, and then call [s appendString:..], or you can also call [s appendFormat:[NSString stringWithFormat:#"",];

Pass an NSString variable to a function and modify it

I'm new in objective-c, this is my first post. This is my problem:
In my main file I have a variable: NSString *var;
Then I have a function:
-(BOOL) myfunction:(NSString *)myvar {
myvar = #"OK!";
return YES;
}
Now in the main file I do:
NSString *var;
BOOL control = myfunction:var;
if(control)
NSLog(#"var is: %#",var);
but the output is "var is: ". If I built in debug mode, and put a breakpoint at the start of function myfunction the memory address of myvar is equal to var, but after the assignment the address of myvar is different from the address of var. How can I solve it? thanks in advance!
While the answers given so far are correct. I think a more pertinent question is why you would want to do this.
It looks you want to have a defensive programming style where the return code indicates success or failure.
A more Objective-C like way to do this would be to pass the string and an NSError ** as a parameter and return the string or a nil to indicate failure as described in the Error Handling Programming Guide
So the way to write this would be:
- (NSString *)aStringWithError:(NSError **)outError {
returnString = #"OK";
if (!returnString) {
if (outError != NULL) {
NSString *myErrorDomain = #"com.company.app.errors";
NSInteger errNo = 1;
*outError = [[[NSError alloc] initWithDomain:myErrorDomain code:errNo userInfo:nil] autorelease];
}
}
return returnString;
}
And to use it:
NSError *error;
NSString *stringVariable = [self aStringWithError:&error];
if (!stringVariable) {
// The function failed, so it returned nil and the error details are in the error variable
NSLog(#"Call failed with error: %ld", [error code]);
}
This is a trivial example, but you can see that you can construct and return far more meaningful information about the error rather than just whether it succeeded or not.
You can also use NSMutableString.
-(BOOL) myfunction:(NSMutableString *)myvar {
[myvar setString:#"OK!"];
return YES;
}
and change your call site as follows:
NSMutableString *var = [NSMutableString string];
BOOL control = [self myfunction:var];
if(control)
NSLog(#"var is: %#",var);
Syntactically you need to fix your myFunction invocation like so:
BOOL control = [self myfunction:var];
The real problem here is that inside of myFunction you are assigning a string value to a local string variable only, whereas you want to change the underlying string that it points to. This is usually the wrong approach in Obj-C, but you can do it like so:
-(BOOL)myfunction:(NSString **)myvar
{
*myvar = #"OK!";
return YES;
}
NSString *var;
BOOL control = [self myfunction:&var];
if(control)
NSLog(#"var is: %#",var);

Iphone substring causing memory leak

Im just wrapping up my app, so im onto the stage of running instruments to identify leaks in the app. Ive come across a leak that I cannot work out why it is being registered as a leak.
I have the following lines for example:
NSString *imageType = [[[NSString alloc] initWithString:[loopString substringToIndex:[loopString rangeOfString:#"</IMAGE>"].location]] autorelease];
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + :#"<IMAGE>".length];
So basically all im doing is pulling out a section of the "loopstring" and putting that into the imagetype string than just cutting off the trailing fluff of the string using the SubstringFromIndex method.
When I run instruments it says "NSCFString substringwithRange" leak. It highlights the second line:
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + :#"<IMAGE>".length];
I would think the substringFromIndex method should return a string that is automatically added to the autorelease pool.
Any ideas on where im going wrong?
Thanks
Following is the refactored code:
- (void)SetupTop10:(NSString *)Top10Data
{
while (Top10Data != #"") {
NSLog(Top10Data);
if ([Top10Data rangeOfString:#"</TOP10ENTRY>"].location == NSNotFound){
Top10Data = #"";
}
else
{
NSString *loopString = [Top10Data substringToIndex:[Top10Data rangeOfString:#"</TOP10ENTRY>"].location + 13];
Top10Data = [Top10Data stringByReplacingOccurrencesOfString:loopString withString:#""];
//NOW CREATE A RECORD FOR THIS ITEM
NSString *imageType = [loopString substringToIndex:[loopString rangeOfString:#"</IMAGE>"].location];
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + 7];
NSString *displayText = [loopString substringToIndex:[loopString rangeOfString:#"</DISPLAYTEXT>"].location];
displayText = [displayText substringFromIndex:[displayText rangeOfString:#"<DISPLAYTEXT>"].location + 13];
NSString *link = [loopString substringToIndex:[loopString rangeOfString:#"</INTERESTID>"].location];
link = [link substringFromIndex:[link rangeOfString:#"<INTERESTID>"].location + 12];
[Top10Images addObject:imageType];
[Top10Links addObject:link];
[Top10s addObject:displayText];
Top10RowCount = Top10RowCount + 1;
}
}
[self.Top10Table reloadData];
Top10Table.hidden = NO;
loadingLabel.hidden = YES;
loadingIndicator.hidden = YES;
}
//******************
It doesn't look leaky. But why
NSString *imageType = [[[NSString alloc] initWithString:
[loopString substringToIndex:[loopString
rangeOfString:#"</IMAGE>"].location]
] autorelease];
if you effectively get the same with
NSString *imageType = [loopString substringToIndex:[loopString
rangeOfString:#"</IMAGE>"].location];
with half the memory usage?
Leaks will tell you where the leaked memory was allocated. If you click around (there's a right-arrow icon by the memory address, I think) then you can look at all the allocations/retains/releases for that addresses.
In this example, Leaks will point you to the first line, when it's the fifth one that "leaks" (actually it's a missing release in dealloc/on assignment that leaks):
NSString * s = [someString substringFromIndex:1];
[myArray addObject:s];
// ...
NSString * s2 = [myArray lastObject];
instanceVariable = [s2 retain];
// ... and forget to release in dealloc
What does tableView:cellForRowAtIndexPath: do?
I can't see any problem in the above code. Did you release Top10Images in your dealloc method?

variable parameter function - EXC_BAD_ACCESS when calling [obj release];

I have the following method:
(void)makeString:(NSString *)str1,... {
va_list strings;
NSString *innerText = [[NSString alloc] init];
NSString *tmpStr = [[NSString alloc] init];
if (str1) {
va_start(strings, str1);
while (tmpStr = va_arg(strings, id)) {
innerText = [innerText stringByAppendingString:tmpStr];
}
label.text = [str1 stringByAppendingString:innerText];
}
[tmpStr release];
}
I will eventually get to Objective C Memory Management reading, where I'm sure I will find the answer to this - probably related to pointers and copying - , but for now, can anyone explain why if I add [innerText release]; as the last line of this function, i get an EXC_BAD_ACCESS error at runtime?
First, your code is erroneous.
As far as I can see you are only concatenating the strings to assign the result to label.text.
I assume that label is an ivar, so label.text = … ist legal. Then the following should do it:
- (void)makeString: (NSString *)str1, ...
{
if (str1) {
NSString *tmpStr;
va_list strings;
va_start(strings, str1);
while (tmpStr = va_arg(strings, id)) {
str1 = [str1 stringByAppendingString: tmpStr];
}
label.text = str1;
}
}
Some notes:
You should not release any input parameter unless your method is about releasing something.
As the first answer stated, you should not release the result of stringByAppendingString: unless
you have retained it before.
[Update]
I changed the answer because it contained an error. label.text = str1 should retain str1 of course (if it wants to keep it). Especially the calling code should not retain str1 unless it wants to keep it for itself.
stringByAppendingString returns an autoreleased string, which is replacing your original assignment. So your release is not needed. But you are leaking memory with the two allocs above.
You should probably use [NSString initWithCString:va_arg(strings, id)] to assign the tmpStr too.

iPhone + NSString error

I have static NSString as below:
static NSString *bowlerName;
In the code I am assigning it with some value as below:
-(void)setBowlerSpecifications:(int)playerId
{
Player *objPlayer = [CricketManagementDAL getBowlerSpecification :playerId];
[objPlayer retain];
bowlerSpecialSkill = objPlayer.specialSkill;
bowlerType = objPlayer.type;
bowlerName = objPlayer.playerName; // <------------
[objPlayer release];
}
Now, if I am referring to the same variable bowlerName in code anywhere else, I get the error: Variable is not a CFString.
Please help me.
It is an NSString but you are using it elsewhere in a context that expects a CFString, you can simply cast as follows
CFStringRef aCFString = (CFStringRef)aNSString;