Accessing element in array - Request for member in something not a struture or union
I have created a custom button called ModuleUIButton
which inherits from UIButton
. This custom button has an mutable array property called cycleList
.
I have an mutable array of ModuleUIButton
's called moduleList
. I need to be able to access an element of the cycleList
mutable array, and I use the following call:
//Create ModuleUIButton
ModuleUIButton *newModuleButton = [[ModuleUIButton alloc]
//Customize ModuleUIButton
initWithFrame:CGRectMake(29.0, (200.0+(88*moduleCounter)), 692, 80.0)];
[newModuleButton setTitle:@"Module" forState:UIControlStateNormal];
[newModuleButton setBackgroundColor:[UIColor purpleColor]];
//Add newModuleButton to moduleList array
[moduleList addObject:newModuleButton];
//Access the first element in moduleList which is newModuleButton and add
// a string to it's cycleList property
[[self.moduleList objectAtIndex:0].cycleList addObject:@"new Cycle"];
When attempting to compile however, I get:
Request for member 'cycleList' in something not a structure or a Union
Is the compiler complaining because it doesnt know that moduleList
's开发者_JS百科 0th element will be a ModuleUIButton
? If so, how can I access any of the ModuleUIButton
s properties by referencing it from the mutable array?
Any insight would be appreciated!
Is the compiler complaining because it doesnt know that
moduleList
's 0th element will be aModuleUIButton
?
Exactly. The return type of objectAtIndex:
is id
. The compiler can't know what the actual type is, and can't therefore turn the property access .cycleList
into the correct method call as it normally would, because it can't know what the correct method is.
The property access essentially works by rewriting your code. The complier sees foo.bar
and goes to foo
's class, finds the methods that correspond to the bar
property, and turns what you wrote into [foo bar]
or [foo setBar:]
, as appropriate. The trick is that, since the methods associated with a property can have any name (not just the standard bar
/setBar
) the compiler must be able to determine the type of the object in order to figure out the right method names to use.
When you use the bracket syntax, you're telling the compiler the exact name of the method you want called. It doesn't have to do any lookup, it just turns that into the usual call to objc_msgSend
.
If so, how can I access any of the
ModuleUIButton
's properties by referencing it from the mutable array?
Just use the "standard" syntax:
[[self.moduleList objectAtIndex:0] cycleList]
You can also give the compiler a hint by casting, as Taskinoor suggested:
((ModuleUIButton *)[self.moduleList objectAtIndex:0]).cycleList
This explicitly tells the compiler to treat the object being returned from objectAtIndex:
as a ModuleUIButton
; it can then figure out what the method name should be.
Try to cast like this:
ModuleUIButton *button = (ModuleUIButton *)[self.moduleList objectAtIndex:0];
[button.cycleList addObject:@"new Cycle"];
精彩评论