Out Of Scope Error In Objective C
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us Learn more about Stack Overflow the company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 6.2 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Objective C + out of scope error up vote 0 down vote favorite I am declaring a static NSString in .h file as: static NSString *bowlerName; @interface PlayMatchController : UIViewController
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us Learn more about Stack Overflow the company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 6.2 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Objective C - XCode http://stackoverflow.com/questions/1968805/objective-c-out-of-scope-error not recognizing variable outside of if statement up vote 2 down vote favorite Trying to set a sprite filename with an if statement, then load the proper file based on that string. It looks like there's a problem with my variable scope, but I don't know what it is. Here's my code: if ([[GameManager sharedGameManager] newHighScore] == TRUE) { NSString *highScoreLabelText = @"label-new-high-score.png" } else http://stackoverflow.com/questions/8989335/objective-c-xcode-not-recognizing-variable-outside-of-if-statement { NSString *highScoreLabelText = @"label-high-score.png" } CCSprite *highScoreLabel = [CCSprite spriteWithSpriteFrameName:highScoreLabelText]; [highScoreLabel setAnchorPoint:ccp(0,0)]; [highScoreLabel setPosition:ccp(20, winSize.height * 0.575f)]; [self addChild:highScoreLabel]; XCode is flagging an error, saying that highScoreLabelText is an undeclared identifier, and thus won't compile the app. Do I need to declare something else along with the NSString to get the rest of the code to work with the variable? objective-c xcode cocos2d-iphone scope share|improve this question asked Jan 24 '12 at 15:23 Kevin Whitaker 2,60573364 add a comment| 2 Answers 2 active oldest votes up vote 8 down vote accepted This is because you declared two separate inner-scope variables in both branches of if. Neither of these two variables is visible outside its scope, so you are getting an error. You should move the declaration out of if, like this: NSString *highScoreLabelText; if ([[GameManager sharedGameManager] newHighScore] == TRUE) { highScoreLabelText = @"label-new-high-score.png" } else { highScoreLabelText = @"label-high-score.png" } Now highScoreLabelText is visible outside of your if statement. share|improve this answer answered Jan 24 '12 at 15:25 dasblinkenlight 458k39494846 Nice of you to spell out what i said in code. –MyKuLLSKI Jan 24 '12 at 16:58 @
blocks and variables, including memory management.Types of VariableWithin the block object’s body of code, variables may be treated in five different ways.You can reference three standard types of variable, just as you would from a function:Global variables, including https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html static localsGlobal functions (which aren’t technically variables)Local variables and parameters from an enclosing scopeBlocks http://blog.thepete.net/blog/2010/10/11/common-objective-c-memory-management also support two other types of variable:At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap.const imports.Finally, within a method implementation, blocks may reference Objective-C instance variables—see Object and Block Variables.The following rules apply to variables used within a out of block:Global variables are accessible, including static variables that exist within the enclosing lexical scope.Parameters passed to the block are accessible (just like parameters to a function). Stack (non-static) variables local to the enclosing lexical scope are captured as const variables.Their values are taken at the point of the block expression within the program. In nested blocks, the value is captured from the nearest enclosing scope. Variables local to the enclosing lexical scope out of scope declared with the __block storage modifier are provided by reference and so are mutable.Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope. These are discussed in more detail in The __block Storage Type. Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function. Each invocation of the block provides a new copy of that variable. These variables can in turn be used as const or by-reference variables in blocks enclosed within the block. The following example illustrates the use of local non-static variables:int x = 123; void (^printXAndY)(int) = ^(int y) { printf("%d %d\n", x, y);}; printXAndY(456); // prints: 123 456As noted, trying to assign a new value to x within the block would result in an error:int x = 123; void (^printXAndY)(int) = ^(int y) { x = x + y; // error printf("%d %d\n", x, y);};To allow a variable to be changed within a block, you use the __block storage type modifier—see The __block Storage Type.The __block Storage TypeYou can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __block storage is similar to, but mutually exclusive of, the register, auto, and static stor
to manage your own memory using reference counting. Knowing when to retain and when to autorelease can seem like a black art until you understand the conventions which is used (extremely consistently, I might add) within Objective C libraries. Let's examine one very common mistake, which I will call the Property Assignment Memory Leak. I've seen this a few times, and indeed committed this error myself during my first weeks of iOS development. The code Imagine we have a simple Duck class, which holds a feathers array: @interface Duck : NSObject { NSArray *_feathers; } @property (nonatomic,retain) NSArray *feathers; @end @implementation Duck @synthesize feathers=_feathers; @end during construction we'd like to initialize this array, so we create an init method as follows: - (id) init { self = [super init]; if (self != nil) { self.feathers = [[NSArray alloc] init]; } return self; } Of course, we need to make sure we release our ownership of the feather array during deallocation, so we'll add a dealloc method like so: - (void)dealloc { self.feathers = nil; } The LeakSo we're good here, right? The observant reader will note that no, we're not. the feathers array which we created in our init method will never be released. This will be a little easier to explain if I refactor the init method a little, making it more verbose by introducing a local variable to hold the array we are about to assign to the self.feathers property: - (id) init { self = [super init]; if (self != nil) { // alloc will always create an object with a retain count already set to 1. In other // words, tempArray has ownership of the object. NSArray *tempArray = [[NSArray alloc] init]; // assigning to self.feathers bumps the array's retain count up to 2. In other words, // now the feathers property also has ownership of the object. self.feathers = tempArray; } // when we return tempArray goes out of scope without ever releasing ownership of the object it created. Memory leak! return self; } To make this clearer, I'll try and illustrate what happens as we move through the Duck object's lifecycle. 1) Here an instance of Duck has just been alloced, and we're about to execute init. 2) We create an array, and assign it to the local tempArray variable. Note that any objects created with alloc will already have a retain count of +1 when all