Objective-C syntax - iphone

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)

Related

Get Class of an Object From Superclass in Matlab

Constant properties are static properties(belongs to classes, not instances) in Matlab, like many other OOP languages. And natural way to access them is ClassName.PropName as in Matlab documentation.
However, I couldn't find a way to do ClassName.PropName from a superclass, in a scenario like this:
classdef (Abstract) Superclass < handle
properties(Dependent)
dependentProperty
end
properties (Abstract, Constant)
constantProperty
end
methods
function result = get.dependentProperty(obj)
c = class(obj); % Here I have to get class of obj
result = length(c.constantProperty); % to use here as `ClassName.PropName`
end
end
end
classdef Subclass < Superclass
properties (Constant)
constantProperty = [cellstr('a'); cellstr('b')];
end
end
so that following commands results following outputs this:(expected output)
>> subclassInstance = Subclass()
subclassInstance =
Subclass with properties:
constantProperty: {2×1 cell}
dependentProperty: 2
>> subclassInstance.dependentProperty
ans =
2
>>
But instead, I get following this:(actual output)
>> subclassInstance = Subclass()
subclassInstance =
Subclass with properties:
constantProperty: {2×1 cell}
>> subclassInstance.dependentProperty
Struct contents reference from a non-struct array object.
Error in Superclass/get.dependentProperty (line 13)
result = length(c.constantProperty);
>>
Also tried: c = metaclass(obj) which gives "No appropriate method, property, or field 'constantProperty' for
class 'meta.class'."
Question: Is there any way to obtain class of an object from superclass, to be able write a statement like ClassName.PropName?
EDIT:
I know I can reach from object reference like this:
function result = get.dependentProperty(obj)
result = length(obj.constantProperty);
end
But this is not what I want as it makes reader to think constantProperty is an instance property. Also this is not documented in Matlab, instead documentation says ClassName.PropName and this makes me think that there must be a way.
The right way to do this in matlab is through the instance, as per the part of my previous answer you have now incorporated in your question. This is because matlab's object-orientation model is "instance" based.
The constant property is an instance property; it just happens to be the same (i.e. constant) in all instances. Presumably, this is why it's called "constant", not "static": it does not refer to a single static item in memory, like in c; instead every instance is instantiated with that same constant value.
You gain nothing by going out of your way to call it via a "class reference" (no such thing exists btw; unlike python and julia, class prototypes are not objects that can be referred to, nor do they have a type themselves).
However, if you insist, there does happen to be a way to do this using metaclasses, since a constant property set from within the constructor will have a default value named in its metaclass profile
subclassInstance = Subclass();
m = metaclass(subclassInstance);
mp = findobj (m.PropertyList, 'Name', 'constantProperty');
mp.DefaultValue
Also, to address why class(subclassInstance).constantProperty doesn't work, this is simply because the result of class(subclassInstance) is a string (whose value happens to be the classname), not a "reference" to a class (like I said, such a thing doesn't exist in matlab).
However, if you wanted to, obviously you could use such a classname string within an eval statement, to evaluate it as if you were typing it directly in the terminal to access the constant property. So this is another way of achieving what you're after:
eval([class(subclassInstance) '.constantProperty'])
but in theory eval statements should generally be avoided unless there's no alternative.
Short note:
in Java this is possible by this.getClass()
In java this is called reflection, and it's java's own mechanism for 'inspecting' objects. When you do something like myObject.getClass(), what you're returning is still not a "reference to a class prototype". It's an instance of type Class. I.e. even in java, you can't do myObject.getClass().aStaticProperty. But you can use the getFields method provided by the Class class to obtain Field objects, and inspect their value with respect to specific object instances; for static fields, this instance simply becomes the null object.

Objective C Methods and syntax

I am a bit confused when working with objective-c. This part in particular confuses me a lot.
What is the purpose and/ or difference between writing code like this ...
object = [object method];
and
[object method];
Learning objective-c up until now, I always assumed that I could do something like this..
say I had already created this..
NSString *object = [[NSString alloc]initWithFormat:#"%#"];
then I could do what I want with that like so..
[object applyAnyMethodHere];
but now I'm seeing things like this ..
object = [object applyAnyMethodHere];
What is the difference between these two?
The first one (object = [object method];) is an assignment of whatever method returns.
The second one ([object method];) is just calling the method without paying attention to its return value (if any).
The third (NSString *object = [[NSString alloc]initWithFormat:#"#"]) declares variable and assigns the return value of the initWithFormat method called on the return value of the alloc class method.
In many programming languages, object = [object method]; is what is called an "assignment" statement. Consider:
x = y + z;
The statement is read by the computer from right to left to mean:
Calculate the sum of the variables y and z and then store it in the variable called x.
The contents of the right side of your expression don't matter so much as what is actually happening in the whole statement. In your example, the computer will:
Tell an object named "object" to perform "method" and store the results back in "object".
However, you don't always want to store the results of a method call. For example, if you want to present an alert view, you may simply call:
[myalertView show];
Notice that there is no assignment happening. Assignment is not required, unless you want to store the value returned by a method call.
Also, consider this:
NSInteger x = 5;
There is no method call, but there is an assignment. Your example of object = [object method]; is simply a more complex version of that.

IPhone SDK - How to detect variable type (float or double)?

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));

NS String comparison fails with stringWithFormat

I have two NSStrings with the same value
this failed for me:
if (button.controlName == controlName) {
return button;
}
this worked:
if ([button.controlName compare: controlName] == NSOrderedSame) {
return button;
}
Is this just how strings are compared in objective c? Or should the first statement have worked as well? Why might the first statement have failed? I know it worked for other strings.
The strings it does not work for are initialized like this:
button.controlName = [NSString stringWithFormat:#"controlName%d", i]
With NSString you should use isEqualToString: instead of compare.
[button.controlName isEqualToString:controlName]
Read more the why (and also why it worked for some other strings)
Objective-C is a fairly thin layer on top of standard C. As a result obj-c, just as in normal c, doesn't have operator overloading.
NSString *controlName = #"bobDole";
The above code creates a pointer to the string #"bobDole", controlName is not the value itself, but instead is really just a long integer that says the memory address of an object.
When using pointers and comparing them using the == operator like (mutableCopy is being used to prevent the compiler from optimizing out the validity of this example.)
NSString *string1 = #"bobDole";
NSString *string2 = [string1 mutableCopy];
NSLog(#"%d", string1 == string2);
The above code will always print false (or zero in this case), even though both objects are NSStrings, and both contain the value of #"bobDole". This is because the value of string1 is actually a hex number like 0x0123456 and string2 could be something like 0x0987654. So really the above comparison looks like this to the computer:
NSLog(#"%d", 0x0123456 == 0x0987654);
So when comparing strings (or any other object), always use one of the isEqual methods, never use the == operator.
Now as to why it worked for some other strings:
As mentioned above when using the == operator you're actually doing pointer comparison. You'll also notice in my above example I used mutableCopy instead of the following:
NSString *string1 = #"bobDole";
NSString *string2 = #"bobDole";
The reason I did such was that the compiler will look at those two statements know they share the same immutable value and optimize them so they point at the same value in memory. Thus making the pointer values of the two identical.
The compiler also makes the same optimizations for these methods of string initialization.
NSString *string3 = [NSString stringWithString:#"bobDole"];
NSString *string4 = [NSString stringWithString:string1];
NSString *string5 = [string1 copy];
Because of this optimization by the compiler and runtime all 5 pointers point to the same memory location and are thus equal to each other when compared via ==.
This may be kinda long, but I tried to make it accessible and understandable. Hope it helps.
1st statement just compares pointers, but not string values, so to compare strings you should use -isEqualToString as Bryan points.
There's a method called isEqualToString to compare two NSStrings.
if([button.controlName isEqualToString:controlName])
...

What does the & symbol mean in Objective-C?

What does the & symbol mean in Objective-C? I am currently looking at data constucts and am getting really confused by it.
I have looked around the web for it but have not found an answer at all. I know this is possibly a basic Objective-C concept, but I just can't get my head around it.
For example:
int *pIntData = (int *)&incomingPacket[0];
What is the code doing with incoming packet here?
& is the C address-of unary operator. It returns the memory address of its operand.
In your example, it will return the address of the first element of the incomingPacket array, which is then cast to an int* (pointer to int)
Same thing it means in C.
int *pIntData = (int *)&incomingPacket[0];
Basically this says that the address of the beginning of incomingPacket (&incomingPacket[0]) is a pointer to an int (int *). The local variable pIntData is defined as a pointer to an int, and is set to that value.
Thus:
*pIntData will equal to the first int at the beginning of incomingPacket.
pIntData[0] is the same thing.
pIntData[5] will be the 6th int into the incomingPacket.
Why do this? If you know the data you are being streamed is an array of ints, then this makes it easier to iterate through the ints.
This statement, If I am not mistaken, could also have been written as:
int *pIntData = (int *) incomingPacket;