Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Palad1

macrumors 6502a
Original poster
Feb 24, 2004
647
0
London, UK
Hello,

My C is a bit rusty, and coming from .Net I am bound to do some stupid things... Could anyone explain why declaring pointers isn't allowed in a switch statement?

Here's my code:

Code:
NSString* outerScope=nil;
switch(myEnum){
  case kMyValue1:
    NSString* innerScope=@"InnerScope"; // Generates an error: unexpected token '*'
    outerScope=@"OuterScope"; // works
    for(int i=0;i<2;i++){ // works and also declares a variable in the statement
      NSLog(@"declared i and iterates over it... %d",i);
    }

    break;
  case kMyValue2:
    // and now for something completely different
    break;
}

So how come I cannot declare a pointer in my switch statement? I bet $DEITY is killing kittens when I try declaring variables in there, but I'm a bit lost here...

Bonus question :
Let's suppose I were to develop using a custom gui toolkit for an undisclosed embedded device, and would like to change the text of a IUBoutonArrondi by calling :
Code:
IUBoutonArrondi definirTitre:(NSString*) pourEtat:(int)

Am I responsible for freeing the NSString* passed as an arg?

Here's what I am currently doing:
Code:
NSString* str = [[NSString alloc] initWithCString("Bonjour Monde")];

[leMagnifiqueBouton definirTitre:str pourEtat:0x1]; //assign the text to the widget

// cleanup
[str release]; // do I need to do this? What if str was assigned a const as in str=@"foo";

I guess Java/.Net really spoiled me on the memory management side of programming.

Thanks for your help, insight, and your surrender-monkey jokes.
 

Sander

macrumors 6502a
Apr 24, 2008
521
67
Regarding the declaration-inside-switch case: Simply enclose the code in your case in a scope (curly braces). Otherwise, the NSString is declared in a sort of zombie-scope.

When you pass in a pointer to a function, it is rare for the function to "take ownership" of it. So it's still yours.
 

Palad1

macrumors 6502a
Original poster
Feb 24, 2004
647
0
London, UK
Thank you.

When you pass in a pointer to a function, it is rare for the function to "take ownership" of it. So it's still yours.

Is the ownership transfer documented somewhere? In that case, I'd assume the method makes a copy of the value I am passing then.

Cheers!
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
Is the ownership transfer documented somewhere? In that case, I'd assume the method makes a copy of the value I am passing then.

If you create an object (e.g. via alloc & init, or copy) then it has a retained count of 1. You MUST call release (or autorelease) for it ever to be freed.

If you call a function which creates an object and returns it, then you don't have to release it.

There's an obvious problem here. If you write a function which creates (say) an NSString and returns it, how can you release it, and return it to the calling function. It would seem you can't do both. Well, you can. In this scenario, use autorelease. This says "I don't need this object any more, so if the caller needs it to hang around, it better retain it, or else it's going to be deleted".

So, the guidelines are:
If you create an object, YOU must release/autorelease it.
If you create an object in a function and return it, you probably should autorelease it.
If you call a function and it returns an object, you should retain it if you need it later on (i.e. outside the current scope).
If you retain an object, you must release/autorelase it.

Best of luck,
Beer swilling top-o-the-mornin' monkey.
 

Palad1

macrumors 6502a
Original poster
Feb 24, 2004
647
0
London, UK
Thanks whooleytoo.

So my widget factory method should look like this:

Code:
- NSString* ToPaddy:(NSString*)french
{
  NSString* paddy=nil;
  if([@"bonjour"] isEqualToString:french){
     paddy=@"Mornin' lad, let's get berco at the battle cruiser!";    
  }else{
     paddy= @"Wot?!?";
  }
  return [paddy autorelease];
}
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
My understanding is that strings created with the @"My string here" construct as "special" and don't need to be autoreleased.

Edit: see the documentation here. Strings created via the method are never deallocated...
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
Thanks whooleytoo.

So my widget factory method should look like this:

Code:
- NSString* ToPaddy:(NSString*)french
{
  NSString* paddy=nil;
  if([@"bonjour"] isEqualToString:french){
     paddy=@"Mornin' lad, let's get berco at the battle cruiser!";    
  }else{
     paddy= @"Wot?!?";
  }
  return [paddy autorelease];
}

As Robbie says above - this is kind-of a special case I missed out on. If you just have a constant string as you have, you don't need to release it. You didn't create a new object via alloc or copy, so the rule about releasing it doesn't apply.

If your code was as below, the autorelease would be needed. I've also corrected your strings, which were waaaay off! :)

Code:
- NSString* ToPaddy:(NSString*)french
{
  NSString* paddy=nil;
  if([@"bonjour"] isEqualToString:french){
     paddy=[[NSString alloc] initWithString: @"Hey, how's the craic? Fancy one on the way home?"];    
  }else{
     paddy= [[NSString alloc] initWithstring: @"Wha?!?"];
  }
  return [paddy autorelease];
}
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
That's still wrong. You mean

Code:
  if([@"bonjour" isEqualToString:french])

Oops, didn't spot that one.

And I'm not sure that works either - can you send messages to a constant string? I have a feeling you can't. So it needs to be either:

Code:
  if([[NSString stringWithString:@"bonjour"] isEqualToString:french])

or

Code:
  if([french isEqualToString:@"bonjour"])
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
And I'm not sure that works either - can you send messages to a constant string? I have a feeling you can't.

Yes you can. Constant strings are treated as normal NSString objects. You should treat them just the same as any other object in terms of memory management, even though like robbieduncan said they don't get released and are shared.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Oops, didn't spot that one.

And I'm not sure that works either - can you send messages to a constant string? I have a feeling you can't. So it needs to be either:

Code:
  if([[NSString stringWithString:@"bonjour"] isEqualToString:french])

or

Code:
  if([french isEqualToString:@"bonjour"])

I think you can: they are just another object. If you can't the second is far better than the first: it doesn't create another object.

For example if we had
Code:
NSString *constantLiteral = @"TryMe"
if ([constantLiteral isEqualToString:@"OrMe"])
{
}

that would look fine. I don't think inserting the variable really changes anything does it?
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
Yes you can. Constant strings are treated as normal NSString objects. You should treat them just the same as any other object in terms of memory management, even though like robbieduncan said they don't get released and are shared.

Well, you learn something new every day. Problem is, I forget twice as much.
 

Palad1

macrumors 6502a
Original poster
Feb 24, 2004
647
0
London, UK
Thanks for all the tips!

I also learned that I shouldn't trust a Scotsman to teach me some Irish...

Regarding the test on the string itself :
Code:
[@"bonjour" isEqualToString:french]

That's me thinking in .Net/Java and worrying about null reference exceptions...

Now that Robbie shed some light on it, I think that this will also work:

Code:
NSString* who=nil;
if([french isEqualToString:@"bonjour"]){
 // insert way-off string here
}else{
  NSLog(@"Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.");
}

Cheers,
Palad1
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Not sure what you latest example is meant to show: you've declared a NSString* variable that is pointing at nothing (==nil), but you've not used it!

But regardless note that in Object-C/Cocoa messaging nil should not crash the app, at least on it's own...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.