I have 2 different classes but same primitive type declaration as you see below
int x = 0;
- (void)viewDidLoad{
[super viewDidLoad];
}
if I change one of them name "x" to "y" there is no error? WHY? seperate classes same variable whats the problem???
That's because the variable x is shared among classes. I think (but never tried) if you declare extern int x in another file, you could share the x variable.
Try static int x = 0. In general, always declare an internal class variable as static unless you want to share it with another file.
I meet the question. As Says , because the variable x is shared among classes. Modify the variable x to another name.
Related
We have a script that defines values to names similar to #define in c. For example:
script.m:
ERR_NOERROR = 0;
ERR_FATAL = 1;
This script already exists and is used for value replacement when reading data from files.
Now we have a function (or more) that does some analysis and we would like to use the same definition in this function to avoid magic numbers. But when the script is called from the function we get an error.
Attempt to add "ERR_NOERROR" to a static workspace.
See MATLAB Programming, Restrictions on Assigning to Variables for details.
And this does not help much in the understanding of the problem.
The question is how can we make these definitions visible/usable in the functions with having to copying it every time.
Example:
function foo = bar(a)
run(script.m) %also tried running it without the run command
if a == ERR_NOERROR
foo = 5;
else
foo = 6;
end
end
edit:
There was a nested function,below in the function which I was not aware of. This explains the problem.
This kind of scoping error happens when you use nested or anonymous function within a function. The solution is well documented.
To your case, you can avoid nested function, or "Convert the script to a function and pass the variable using arguments", as the documentation suggests.
EDIT: I should have made it clear that the error occurs even if the script is not called within the nested function. Similar scenario is that, in debug mode (by setting up a break point), it will be an error if one tries to create a temporal variable to test something.
This is not a direct answer, rather a recommendation to switch to another method, which will not be mixing scope and workspace.
Instead of defining your constant in a script, you could make a class containing only constant properties. ex: code for error_codes.m:
classdef error_codes
% ---------------------------------------------------------------------
% Constant error code definition
% ---------------------------------------------------------------------
properties (Constant = true)
noerror = 0 ;
fatal = 1 ;
errorlvl2 = 2 ;
errorlvl3 = 3 ;
warning = -1 ;
% etc ...
end
end
I use this style for many different type of constants. For tidiness, I groups them all in a Matlab package directory (The directories which starts with a + character.
The added benefit of using constant class properties is the safety that the values cannot be changed in the middle of the code (your variables defined in a script could easily be overwritten by a careless user).
So assuming my file error_codes.m is placed in a folder:
\...somepath...\+Constants\error_codes.m
and of course the folder +Constants is on the MATLAB path, then to use it as in your example, instead of calling the script, just initialise an instance of the class, then use the constant values when you need them:
function foo = bar(a)
ERR = Constants.error_codes ;
if a == ERR.noerror
foo = 5;
else
foo = 6;
end
or it can works in switch statement too:
switch a
case ERR.noerror
foo = 5 ;
case ERR.warning
foo = 42 ;
case ERR.fatal
foo = [] ;
end
when i write var x = 0
I know that x is an object that has properties and methods (created from Int Structure).
Where and how does x store the 0 ?
Is the 0 stored as a property of x ?
If yes, what would be the type of that property ?
If not, where is it stored ?
x is not an object, strictly speaking. "Object" is a name we give to instances of classes, not structs. x is an instance of the Int struct.
The Int structure wraps a Builtin integer type, and defines a bunch of methods you can call on it. That builtin integer literal type isn't accessible from Swift (nor is there a reason for it to be). Like all structures, instances of Int are stored on the runtime stack. They're not objects on the heap like Integer in Java, for example.
You can see the implementation details of (U)Int(8/16/32/64) here. This file uses the Generate Your Boilerplate (GYB) preprocessor created by the Swift team to generate .swift files from .swift.gyb template files.
On line 221, you can see the property _value of type Builtin.${BuiltinName}. The GYB preprocessor expands this out so that Int has a _value of type Builtin.Int, Int64 has Built.Int64, etc.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
As everyone knows, JavaScript "Hoists" the variables to the top of the file or scope. But from my understanding, using let is the same as var only let is confined to the scope it is defined in.
Being a compiled language instead of an interpreted, can we assume Swift does NOT do this?
For example:
x = 10
var y = x + 10
var x
can we assume Swift does NOT do this?
You can assume whatever you want, but no matter the programming language, your absolute best bet it to just try it and find out. If you would have pasted your sample code into a Playground or in any Swift-capable IDE, or just tried running it through the command line, you'd quickly find out that this simply does not work.
Your question is somewhat confusing, but I think I can address all or at least most of your questions.
x = 10
var y = x + 10
var x
Assuming there is no other code to go with your original sample, it simply does not compile. All three lines have a problem.
The first two lines complain about the use of an unresolved identified 'x'. In English, this means Swift can't figure out what variable you're talking about. Variables in Swift must be declared before they are used, so the declaration on line three doesn't help the next two lines.
The third line complains that it can't figure out what type x should be. "Type annotation missing in pattern". In some cases, Swift can figure out what type our variable should be. For example, with var x = 10, Swift can figure out that x's type should be Int. If we want something else, we must specify. But if we aren't assigning a value in the declaration, Swift has no idea and must be told: var x: Int?
What about the case where x exists at a different scope?
Well, Swift allows variable shadowing. That is to say, a variable declared at one scope hides a variable declared at another scope.
So, for example:
class Foo {
let x = 10
func foo(value: Int) -> Int {
let a = value * self.x
let x = 10
return a * x
}
}
Now we can use some x before we've declared a locally scoped x, but these are different variables. Also, perhaps most importantly, notice the self. prepended to x here. It's required. Without it, Swift will refuse to compile this code and will complain: "Use of local variable 'x' before its declaration."
However, within functions of classes is not the only place we can shadow variables. We can also do it within if blocks (among other places) which is where things can get a little more confusing. Consider this:
class Foo {
let x = 10
func foo(value: Int) -> Int {
print(x)
if x > 3 {
let x = 2
print(x)
}
return x
}
}
Here, we've used x twice before declaring it. And we didn't have to make use of the self. and it doesn't complain and compiles perfectly fine. But it's important to note that outside the if block (including the x > 3 conditional) the x we're referencing is the instance variable, but inside the if block, we've created a new variable called x which shadows the instance variable. We can also create the same sort of shadowing by using if let and if var constructs (but not guard let).
The result of calling this function will be that the value 10 is printed, we enter the if block, the value of 2 is printed, then we exit the if block and the value of 10 is returned.
Now let's through var into the mix here. First, if you aren't already aware, you should start by reading this which explains the difference between let and var (one is a constant, the other is not).
Let's combine let vs var with scoping and variable shadowing to see how it effects things.
class Foo {
let x = 10
func foo(value: Int) -> Int {
print(x)
if x > 3 {
var x = 2
while x < 10 {
print(x)
x += 3
}
return x
}
return x
}
}
Okay, so this is the same as before but with a slightly more complicated bit within the if block.
Here, our locally-scoped variable is declared as a var while our instance variable remains a constant let. We cannot modify the instance variable, but we can modify the local variable. And we do so, on each iteration of the while loop.
But importantly, this variable is an entirely different variable from the instance variable. It might as well have a completely different name (and in practice, it basically always should have a different name). So modifying our local variable x doesn't change anything about our more broadly scoped instance variable x. They're different variables that reside in different memory locations. And once a variable is declared as a let or a var, that variable cannot be changed to the other.
'let' and 'var' do not have a difference in scope.
Global variables are variables that are defined outside of any
function, method, closure, or type context. Local variables are
variables that are defined within a function, method, or closure
context.
How do I detect whether a variable is float, double, int, etc.?
Thanks.
Objective-C is not like PHP or other interpreted languages where the 'type' of a variable can change according to how you use it. All variables are set to a fixed type when they are declared and this cannot be changed. Since the type is defined at compile time, there is no need to query the type of a variable at run-time.
For example:
float var1; // var1 is a float and can't be any other type
int var2; // var2 is an int and can't be any other type
NSString* var3; // var3 is a pointer to a NSString object and can't be any other type
The type is specified before the variable name, also in functions:
- (void)initWithValue:(float)param1 andName:(NSString*)param2
{
// param1 is a float
// param2 is a pointer to a NSString object
}
So as you can see, the type is fixed when the variable is declared (also you will notice that all variables must be declared, i.e. you cannot just suddenly start using a new variable name unless you've declared it first).
In a compiled C based language (outside of debug mode with symbols), you can't actually "detect" any variable unless you know the type, or maybe guess a type and get lucky.
So normally, you know and declare the type before any variable reference.
Without type information, the best you can do might be to dereference a pointer to random unknown bits/bytes in memory, and hopefully not crash on an illegal memory reference.
Added comment:
If you know the type is a legal Objective C object, then you might be able to query the runtime for additional information about the class, etc. But not for ints, doubles, etc.
Use sizeof. For double it will be 8. It is 4 for float.
double x = 3.1415;
float y = 3.1415f;
printf("size of x is %d\n", sizeof(x));
printf("size of y is %d\n", sizeof(y));
I've been studying objective-c for a few days now. I keep coming across these two structures:
NSString * somestring
(NSString *) somestring
I understand the first simply sets a pointer to an NSString object, but what does the second construct do, and when should I use it?
What's the deal with the asterix marks?
Sorry if this question doesn't make any sense, I am completely new to this language, and haven't even reached the level of asking proper questions.
Main purpose -- I'm trying to decipher this method:
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger) row forComponent: (NSInteger)component
**Also, the classes I chose don't matter. **
What you want to understand is the method declaration syntax. In Objective-C, a method has a name which looks like this doSomethingWith:andAlso:inMode:. Each colon precedes an argument. When you declare or define a method, you also specify the types of the variables and their names; the type is given in parentheses. You also prepend things with a - for instance methods and a + for static methods, as well as the (parenthesized) return type. Now, you have
- (NSString*) pickerView:(UIPickerView*)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
...
}
When we decipher this, we find that:
-: It's an instance method.
(NSString*): The return type, NSString*.
pickerView:: The first part of the method name.
(UIPickerView*)pickerView: The first argument; its name is pickerView and it has type UIPickerView*.
titleForRow:: The second part of the method name.
(NSInteger)row: The second argument; its name is row and its type is NSInteger.
forComponent:: The third part of the method name.
(NSInteger)component: The third argument; its name is component and its type is NSInteger.
Thus, putting it all together, this defines the instance method pickerView:titleForRow:forComponent:; it returns an NSString*, and the three arguments it takes are of type UIPickerView*, NSInteger, and NSInteger, respectively. This method would be called as [obj pickerView:myPV titleForRow:myRow forComponent:myComponent].
And just for further reference: in isolation, if you have NSString* str, it declares a variable of type NSString*; and if you have (NSString*)obj, it (forcefully) converts that object to have type NSString*. This has no connection to the method declaration syntax.
Edit 1: I also saw that you were asking about the asterisks. In (Objective-)C, this represents a pointer. If you have an int x, say, then when you write int y = x and then y = 3, the original value of x is unchanged. If, however, you have an int* px, then you can write px = &x. (Note that ints, declared as int, are a completely different data type than int pointers declared as int*. Writing int y = &x is garbage, as is int* py = x, and so on.) This & is the "address of" operator; it finds where x is in memory and returns it. Now, if you write int* py = px and then py = &y, this won't change px. But if you write *px, you access the value currently stored in x, and you can change it: *px = 42 sets x to 42. For various reasons, when working with objects, people tend to like to work with references to them instead of their actual values; thus, in Objective-C, you only handle objects through pointers. What this means is that you will never see NSMutableArray x, only NSMutableArray* x; and that if you have NSMutableArray* y = x, then x and y are, roughly speaking, the same, and calling [x addObject:obj] affects y as well. There are more comprehensive tutorials out there—it's worth checking them out if you don't understand pointers—but this should suffice as an overview.
Edit 2: In another comment, you say you're coming from Ruby and Python. In Ruby (and I think Python, but I've used it less), every variable is a reference. This means that the basic use of pointers for object types should be familiar; as long as you never use & or *, they'll function in pretty much the same way. The difference between pointers and references is that you can take references to objects and create pointers to pointers. For instance, many methods end in ...error:(NSDictionary**)error. This effectively provides an extra return value; in the method, if something goes wrong, they can write *error = myErrorInfo. Since function arguments are copied, error = myErrorInfo wouldn't be visible; however, the pointer's referent is still the same, and so it can be assigned to. If you then write code such as:
NSDictionary* errorDict = nil;
[obj unsafeOperation:#"http://stackoverflow.com" error:&errorDict];
You pass in a pointer to errorDict so that the unsafeOperation:error: method can write to errorDict and you can see it.
mebFace - an asterisk represents a pointer. So whenever you see (eg) "NSString *" then it means you're dealing with a pointer to a NSString object. The method you're trying to decipher returns a pointer to a string as the result. It takes three parameters: a pointer to a UIPickerView, followed by a couple of integers. The reason that you don't use an asterisk in conjunction with the integers is because they are simple integers - not objects.
You should probably start off by reading a book on the C programming language. This is what Objective-C is built on top of.
Dave
The first one is variable declaration while second is type-casting. I.e. somestring is not of type NSString* so you type-cast it into being NSString*. I believe that the latter case is mostly (if not always) seen on the right side of assignment statement.
In ObjectiveC this comes from C and is also used in many other strictly-typed languages like Java, C# and so on.
In the updated question, your method signature defines that method returns pointer to NSString - (NSString *). And it accepts 3 parameters:
Pointer to UIPickerView object;
number of row;
number of column;
Confusingly, in Objective-c, both of your examples mean different things in different contexts.
When declaring a variable (and other places, but not everywhere else) the asterisk means 'pointer to', ie…
int foo; // An int variable
int *bar; // A pointer to an int
When it comes to objective-c objects we mostly deal with pointers to them, ie.. you will not see this..
NSString myString;
you will always see this
NSString *myString;
The reason why is quite involved, but is to do with where the memory for the object is allocated (the heap) and what happens when you pass a variable to a function or method. A value passed as an argument to a method is copied. It turns out that copying our string when we pass it to a method is probably not what we intended, so we pass a pointer to the string instead, and that is copied. Imagine a string that contains the complete works of Shakesphere, roughly 5 million bytes. It is inefficient to copy it every time we pass it to a method, but a pointer to it is only 4 bytes, and a pointer gives us just as good access to the data because it, well, points to it. This approach wouldn't get us anything for the int argument tho, as the int and the pointer to the int are going to be the same size (or ballpark, at least).
Your second example is a method or a method declaration. It might help to compare it to function definition in something like javascript:
function pickerViewTitleForRowForComponent( pickerView, row, component ) {
...do something here
return result;
}
Objective-c does things slightly better, sorry, i mean differently. The above would basically look like
- pickerView: pickerView titleForRow: row forComponent: component {
...do something here
return result;
}
The arguments are the same: pickerView, row and component. However, the above isn't a valid method because it is missing type info. ie. We must explicitly say what type each argument is and also the type of the object returned from the method.
- (return type)pickerView:(argument type)pickerView titleForRow:(argument type)row forComponent:(argument type)component {
...do something here
return result;
}
As you can probably see, in your example:
return type > a pointer to an NSString object -- (NSString *)
argument1 type > a pointer to a UIPickerView object -- (UIPickerView *)
argument2 type > an NSInteger -- (NSInteger)
argument3 type > an NSInteger -- (NSInteger)