objective c - Why doesn't a generic NSDictionary warn me about incorrectly-typed key inserts/assignments? -


why don't following nsdictionary/nsmutabledictionary calls produce error or warning?

i expect error here because rhs nsdictionary literal doesn't match generic types of nsdictionary lhs local variable.

nsdictionary<nsstring *, nsnumber *> *foo = @{ @(42) : @"foo" }; 

i expect error here because key type doesn't match nsmutabledictionary's key generic type:

nsmutabledictionary<nsstring *, nsnumber *> *foo = [nsmutabledictionary new]; // neither of these calls produces error. :( foo[@(42)] = @(42); [foo setobject:@(42) forkey:@(42)]; 

i see error when try assign improperly-typed value, know generics errors working somewhat:

nsmutabledictionary<nsstring *, nsnumber *> *foo = [nsmutabledictionary new]; foo[@"foo"] = @"bar"; 

causes following warning:

foo.m:81:16: incompatible pointer types sending 'nsstring *' parameter of type 'nsnumber * _nullable' 

why don't literal assignment or improperly-typed keys cause warnings/errors?

i filed radar.

seems limitation/bug of compiler, caused definition of setobject:forkeyedsubscript: method:

- (void)setobject:(nullable objecttype)obj forkeyedsubscript:(keytype <nscopying>)key; 

the protocol conforming requirement somehow hides type requirement keytype. if <nscopying> not present, compiler makes keytype check , warns you.

to confirm this, played code, here results:

@interface mydictionary<keytype, objecttype>: nsobject     - (void)setobject:(nullable objecttype)obj forkeyedsubscript:(keytype <nscopying>)key; @end  ...  mydictionary<nsnumber*, nsnumber*>* dict = [[mydictionary alloc] init]; uibutton *button = [[uibutton alloc] initwithframe:cgrectzero]; dict[@"98"] = @14; // no warnings dict[button] = @14; //warning: sending 'uibutton *' parameter of incompatible type 'id<nscopying>' 

the above code has same behaviour nsmutabledictionary. however, if remove <nscopying> protocol conformance restriction keytype, compiler gives appropriate warning:

@interface mydictionary<keytype, objecttype>: nsobject - (void)setobject:(nullable objecttype)obj forkeyedsubscript:(keytype)key; @end  ...  mydictionary<nsnumber*, nsnumber*>* dict = [[mydictionary alloc] init]; dict[@"98"] = @14; // warning: incompatible pointer types sending 'nsstring *' parameter of type 'nsnumber *' 

note. default you'll warnings object types mismatch, if want receive errors, can either enable treat warnings errors build setting, or treat incompatible pointer type warnings errors one.


Comments

Popular posts from this blog

android - Why am I getting the message 'Youractivity.java is not an activity subclass or alias' -

Making Empty C++ Project: General exception (Exception from HRESULT:0x80131500) Visual Studio Community 2015 -

How to fix java warning for "The value of the local variable is not used " -