Disable passing id-typed objects as params


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

@interface MyWidgetArray : NSObject

- (NSUInteger)count;
- (void)addMyWidget:(MyWidget *)widget;
- (MyWidget *)myWidgetAtIndex:(NSUInteger)index;

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

@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];


@implementation MyWidget




As far as I know, there’s no flag you can turn on to enable that kind of warning. “id” in Objective-C is special, being the wildcard of types. By disallowing id passing, you couldn’t do something like:

because init returns an id.

If you really absolutely cannot have non-MyWidgets in the collection, then you’ll need to check the type in addMyWidget: (e… isKindOfClass:) at runtime and then throw an exception (or something carrying a similar level of smackdownitude)