About a year ago, when I first got into programming, I learned the hard way that variables don't escape the scope of the condition they're created in. For example:
-(void)someMethod {
if (x == y) {
NSString *string = [[NSString alloc] initWithString:@"Foo"];
NSLog(string); //开发者_如何转开发 outputs "Foo" to console successfully
}
...
NSLog(string); // Doesn't work, we're out of the scope of the "if" statement.
}
My question is, is there any way to dynamically create variables within a conditional statement and be able to access them at other times, kind of like if I declared it in my @interface
?
EDIT I guess I didn't explain it well, I meant if I wanted to use it later in other methods.
You just need to declare (and optionally initialize) the variable outside of the if. So something like:
-(void)someMethod {
NSString *string = nil;
if (x == y) {
string = [[NSString alloc] initWithString:@"Foo"];
NSLog(string); // outputs "Foo" to console successfully
}
...
NSLog(string);
}
EDIT
To respond to your clarification, 'string' here is a local variable, local to this method. You have other options like instance variables for example. Instance methods like this one (ones that start with '-') will have access to this instance's (this object's) instance variables.
So you could do:
@interface MyClass : NSObject {
NSString *string; // <<-- This is an instance variable (aka "ivar")
}
- (void)someMethod;
- (void)someOtherMethod;
@end
@implementation MyClass
- (void)someMethod {
string = @"Foo";
}
- (void)someOtherMethod {
NSLog (string);
// will print "Foo" provided someMethod was called before this method
}
@end
Obviously there's more to this than you can get in a short answer. You can have global variables. If you're new to the language, you should read properties as a very useful tool for encapsulating instance variables (useful when you want to get the memory mgmt right). But hopefully that gets you pointed in the right direction at least.
-(void)someMethod {
NSString *string = nil;
if (x == y) {
string = [[NSString alloc] initWithString:@"Foo"];
NSLog(string); // outputs "Foo" to console successfully
}
...
NSLog(string); // Doesn't work, we're out of the scope of the "if" statement.
}
Consider what you're asking. You start with:
-(void)someMethod
{ if (x == y)
{ NSString *string = [[NSString alloc] initWithString:@"Foo"];
NSLog(string); // outputs "Foo" to console successfully
}
...
NSLog(string); // Doesn't work, we're out of the scope of the "if" statement.
}
What would you like the second NSLog
to do? You seem to be requesting that it either work, if the body of the if
statement has been executed, or what? Produce a dynamic "undeclared variable" error?
Now you seem to be wanting:
-(void)someMethod
{ if (x == y)
{ NSString *string = [[NSString alloc] initWithString:@"Foo"];
NSLog(string); // outputs "Foo" to console successfully
}
...
}
-(void)someOtherMethod
{
NSLog(string); // Doesn't work, we're out of the scope of the "if" statement.
}
What do you wish to happen in someOtherMethod
if the body of the if
statement in someMethod
has not been executed?
As @Daniel's solution points out, you can reference a variable provided it is in scope. In the single method case you move the point of declaration out of the if
and into the enclosing method body. In the two method case you move it to the class - as an instance variable.
Now scope isn't the same as lifetime - a variable can exist (be alive), but no be accessible (it is out of scope); the common example is when one method calls another, the calling method's variables stay alive but are inaccessible to the called method.
In a similar way that a variable is in scope does not mean that it has to contain a valid value. That is why @Daniel puts nil
in the variable - you know if a value has been created inside the body of the if
by the value of string
not being nil
.
So maybe this is the "dynamic" behaviour you seem to be seeking - you must declare some way to reference the value (the variable), but you indicate whether it has been created by storing some sentinel (nil
in this case) in the variable.
精彩评论