Is there any way to disable passing id-typed objects as params in method invocations?
I have discovered that the compiler is keeping quiet when I pass id-typed objects as params in method invocations even when the signature of the method specifies a specific class type.
For example, in the following example, I was expecting the errors in cases (1) and (2) but I am getting no errors in cases (3), (4), (5), and (6) contrary to my expectation (where I pass objects of type id to [MyWidgetArray addMyWidget:(MyWidget *)widget]
// main.m
#import <Foundation/Foundation.h>
#import "MyWidgetArray.h"
int main (int argc, const char * argv[])
{
@autoreleasepool {
MyWidgetArray *widgetArray = [[[MyWidgetArray alloc] init] autorelease];
NSArray *array = [NSArray array];
[widgetArray addMyWidget:array]; // (1) Compile error as expected
NSString *string = [NSString string];
[widgetArray addMyWidget:string]; // (2) Compile error as expected
MyWidget *widget = [[[MyWidget alloc] init] autorelease];
[widgetArray addMyWidget:widget];
// Is there any way to get the compiler to complain in the following cases?
// I was horrified when I discovered that there are no compilation errors in those cases.
{
id array = [NSArray array];
[widgetArray addMyWidget:array]; // (3) No compile error!
id string = [NSString string];
[widgetArray addMyWidget:string]; // (4) No compile error!
[widgetArray addMyWidget:[NSArray array]]; // (5) No compile error!
[widgetArray addMyWidget:[NSString string]]; // (6) No compile error!
}
}
return 0;
}
// MyWidgetArray.h - An array for only MyWidget objects
#import <Foundation/Foundation.h>
@interface MyWidget: NSObject
@end
@interface MyWidgetArray : NSObject
- (NSUInteger)count;
- (void)addMyWidget:(MyWidget *)widget;
- (MyWidget *)myWidgetAtIndex:(NSUInteger)index;
@end
// MyWidgetArray.m - An array for only MyWidget objects
#import "MyWidgetArray.h"
// Hiding the array object from the user
//
@interface MyWidgetArray ()
@property (nonatomic, retain) NSMutableArray *array;
@end
@implementation MyWidgetArray
@synthesize array;
- (void)dealloc
{
self.array = nil;
[super dealloc];
}
- (id)init
{
self = [super init];
if (self)
{
self.array = [NSMutableArray array];
}
return self;
}
- (NSUInteger)count
{
return [array count];
}
- (void)addMyWidget:(MyWidget *)widget
{
// Allow only instances of MyWidget
if ([widget isMemberOfClass:[MyWidget class]])
[array addObject:widget];
}
- (MyWidget *)myWidgetAtIndex:(NSUInteger)index
{
assert (index < [array count]);
return [array objectAtIndex:index];
}
@end
@implementation MyWidget
@end