C array of ObjC objects as a Function argument - objective-c

Whenever I am passing an argument of Objective C type A to my function then everything is alright:
- (void) f:(id<A>)argument
However, when it's an array of the same object type, Xcode requires that I add a strong attribute as:
- (void) f:(__strong id<A> [])argument
Any idea why is that?

Related

Using Instance Variables in Functions [duplicate]

Can someone confirm that you cannot access instance variables defined in an Objective C #implementation block from within C style functions of the same class? The compiler is throwing errors saying "XXX undeclared' where XXX is the instance variable name.
Here's an example of what I am explaining:
#interface FontManager : NSObject {
CGFontRef fontRef;
}
static int CstyleFunction() {
NSUInteger emSize = CGFontGetUnitsPerEm(fontRef);
}
I want to verify that I cannot use "fontRef" from withing "CstyleFunction".
Any insight would be greatly appreciated.
A "C style method" doesn't really deserve the name "method", I'd call it a "function" instead as in C.
A C function has no self, so it cannot implicitly access ivars as a method can. If you pass an instance to the C function as a parameter, you can access ivars in the same manner you would access a field in a struct pointer.
#Anomie and #jlehr are correct, the C function has no concept of the FontManager object and its current state, it just happens to live in the same file.
However, if FontManager is a singleton and you make fontRef a property (or create an accessor for it), then it would be possible to access the value within your C class:
static int CstyleMethod() {
FontManager *fm = [FontManager sharedManager];
NSUInteger emSize = CGFontGetUnitsPerEm(fm.fontRef);
}
Bottom line, you can mix-and-match C and ObjC syntax within C functions & ObjC methods. But because C functions have no default reference to self (and the object's associated instance variables), you can only reference ObjC objects that are singletons, stored in a global variable, or passed in as parameters.
That's correct. You seem to be mixing up methods and functions though. Methods exist only in Objective-C. What you're referring to as a 'C style method' is really just a C function.
C is not an object-oriented programming language. Since there's no such thing as an object in C, there's also no such thing as an instance variable in C, so the fontRef instance variable would not be visible in the function you posted, nor for that matter in any other C function in your program.

Objective-c symbols ** & +-

Just when I think I'm getting comfortable with Objective-c the mentioned symbols totally throw me down a rabbit hole...
** a double pointer??
& what sort of things can I do with &reference, is a #property? a full on object? weird pointer razzledazzle?
± I see both a + or a - before method declarations; I've seen Java annotate some datatype declarations by manually typing the + and the magic of compiling in Eclipse would change them to a -
I'm likely asking repetitious questions and/or way outta the ballpark on my guesses; thanks for answers/edits.
You're getting into the C portion that objective-c is built on top of.
** is a pointer to a pointer. Since functions in C take arguments by value, it means you can't change the value of the argument in that function. But, by providing a level of indirection and passing a pointer to the pointer, you can change the value.
& means it's a reference. If an argument takes a ** and you have a * variable, pass a reference to it.
Foo *foo;
[self changeFoo: &foo];
- (BOOL)changeFoo: (Foo **)foo
{
// dereference the double pointer and assign a val = alloc init returns a *
*foo = [[Foo alloc] init];
return YES;
}
A common usage in objective-c / cocoa is NSError. It's essentially an out argument.
NSError *err;
BOOL success = [self doSomething:#"Foo" error:&err];
- (BOOL)doSomething:(NSString*)withData error:(NSError**)error
{
}
As you might know, a pointer points to the address of an object and is the way you reference an object. A double pointer is sometimes used in Objective-C, mainly for returning NSErrors, where you want to get back the address, i.e. a pointer, to an error object (NSError) if an error occurred, thus you pass in a pointer assigned to null and the caller can change that pointer so that it points to the address of another pointer which in turn points to an NSError object.
The ampersand (&) is mostly used by the lower level C APIs, e.g. Core Graphics. They are used to reference things, like the current context. As long as most of your code uses square brackets around its method calls you won't see these very often.
Using a + or a - before a method declarations is used to differentiate between class (+) and instance (-) methods. A class methods is called on the class itself (such as alloc), while a instance method is called on an instance of that object (such as init).
- and + before a method declaration designate an instance method and a static class method. To use an instance method you have to create an object of your class before you can call its method, a static method can be called directly from a class type

Accessing Instance Variable in C Style Method

Can someone confirm that you cannot access instance variables defined in an Objective C #implementation block from within C style functions of the same class? The compiler is throwing errors saying "XXX undeclared' where XXX is the instance variable name.
Here's an example of what I am explaining:
#interface FontManager : NSObject {
CGFontRef fontRef;
}
static int CstyleFunction() {
NSUInteger emSize = CGFontGetUnitsPerEm(fontRef);
}
I want to verify that I cannot use "fontRef" from withing "CstyleFunction".
Any insight would be greatly appreciated.
A "C style method" doesn't really deserve the name "method", I'd call it a "function" instead as in C.
A C function has no self, so it cannot implicitly access ivars as a method can. If you pass an instance to the C function as a parameter, you can access ivars in the same manner you would access a field in a struct pointer.
#Anomie and #jlehr are correct, the C function has no concept of the FontManager object and its current state, it just happens to live in the same file.
However, if FontManager is a singleton and you make fontRef a property (or create an accessor for it), then it would be possible to access the value within your C class:
static int CstyleMethod() {
FontManager *fm = [FontManager sharedManager];
NSUInteger emSize = CGFontGetUnitsPerEm(fm.fontRef);
}
Bottom line, you can mix-and-match C and ObjC syntax within C functions & ObjC methods. But because C functions have no default reference to self (and the object's associated instance variables), you can only reference ObjC objects that are singletons, stored in a global variable, or passed in as parameters.
That's correct. You seem to be mixing up methods and functions though. Methods exist only in Objective-C. What you're referring to as a 'C style method' is really just a C function.
C is not an object-oriented programming language. Since there's no such thing as an object in C, there's also no such thing as an instance variable in C, so the fontRef instance variable would not be visible in the function you posted, nor for that matter in any other C function in your program.

How would I define a mix of Objective-C method parameters?

I would like to do something like this in my program:
[obj list error:&error];
But when I try to define the prototype/method, I get compile errors.
I've tried the following definitions:
-(void)list error:(NSError **)error;
-(void)list:() error:(NSError **)error;
nothing seems to work.
Why is the space between list and error in the method signature. If this is the prototype -
-(void) list_error:(NSError **)error;
list_error expects a pointers address to be passed to it. So, this should work.
[obj list_error:&ptr] ; // Assuming ptr is of type NSError* and is initialized.
I think, you are getting confused when to send more than one parameter to a method. Its simple. Method signature should be -
- ( return_type ) splitOne:(type) arg1 splitTwo:(type) arg2 ;
- indicates instance method. Same is the case for class method too but substitued a + instead of -. And so on the method name can be splitted.
Taking an example of fraction, to set a fraction it needs both numerator and denominator. So,
-(void) setNumerator: (int) n setDenominator: (int) d ;
And to call it -
[ obj setNumerator:10 setDenominator:20 ] ;
What is the need to split the method name ?
Normally, in C this function prototype would be -
void setFraction( int a, int b );
But when seeing the prototype, it isn't obvious whether a is numerator or denominator and is the same with b. That is the reason, why in Objective-C method name may be splitted into parts. In the above example of Objective-C, both the setNumerator and setDenominator forms the method name. And when calling, it's quite obvious to the user, the parameter being passed is what. Hope it helps to resolve your problem.

Method Syntax in Objective-C

Can someone explain this method declaration syntax for me? In this function, the number of rows of a UIPickerView (slot machine UI on the iPhone) is being returned. From my understanding, the Method is called 'pickerView', and returns an NSInteger.
It passes in a pointer to the UIPickerview called 'pickerView' ... first, why is the method called the same name as the parameter?
Next there is NSInteger parameter called component that tells us which component we are counting the rows for. The logic to decide which is in the body of the method.
What is 'numberOfRowsInComponent? It seems to describe the value we are returning, but it is in the middle of the parameters.
- (NSInteger) pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
if (component == kStateComponent)
return [self.states count];
return[self.zips count];
}
Objective-C methods are designed to be self documenting, and they borrow from the rich tradition of Smalltalk.
I'll try to explain what you have here, -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.
- (NSInteger)
This first portion indicates that this is an Objective C instance method that returns a NSInteger object. the - (dash) indicates that this is an instance method, where a + would indicate that this is a class method. The first value in parenthesis is the return type of the method.
pickerView:
This portion is a part of the message name. The full message name in this case is pickerView:numberOfRowsInComponent:. The Objective-C runtime takes this method information and sends it to the indicated receiver. In pure C, this would look like
NSInteger pickerView(UIPickerView* pickerView, NSInteger component). However, since this is Objective-C, additional information is packed into the message name.
(UIPickerView*)pickerView
This portion is part of the input. The input here is of type UIPickerView* and has a local variable name of pickerView.
numberOfRowsInComponent:
This portion is the second part of the message name. As you can see here, message names are split up to help indicate what information you are passing to the receiver. Thus, if I were to message an object myObject with the variables foo and bar, I would type:
[myObject pickerView:foo numberOfRowsInComponent:bar];
as opposed to C++ style:
myObject.pickerView(foo, bar);.
(NSInteger)component
This is the last portion of the input. the input here is of type NSInteger and has a local variable name of component.
In Objective-C, the name of a method is composed of all of the portions of the declaration that are not arguments and types. This method's name would therefore be:
pickerView:numberOfRowsInComponent:
The method would be equivalent to a C-style function that looked as follows:
edit: (with thanks to Jarret Hardie):
NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
Adding to the previous answers, I'd just like to say that Objective-C methods (or messages if you prefer) have external and internal parameter names.
So in this case:
- (NSInteger) pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
numberOfRowsInComponent is the external name, the one that you would use when calling this method from the outside.
And component is the internal name of the parameter, the one you use to refer to the parameter from inside of the method.
Hope that clears it up a bit.
It seems to me that Objective-C method signatures are more like sentences. Each parameter deserves a part in method's name. For instance, in C we could have a method (setPersonData) for setting some information about person:
void setPersonData( char* name, int age, float height ) {
and in Objective-C the method would be more descriptive (setPersonName:andAge:andHeight:), like
- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {