objective c - What is the purpose of declaring a protocol for a variable? -
i have been reading protocols on objective-c cannot grasp this:
consider line
person <coordinatesupport> *person = [[person alloc] init];
what purpose of declaring variable conform protocol coordinatesupport
? compile time, xcode can warn me if assign different person
or there purpose @ run time?
i cannot see how variable can conform protocol. ok, class easy see, because can have protocol defining methods want class follow ivar?
i not seeing it.
the standard pattern when declaring variable conforms protocol give "any object" type, id
. declaring variable both has specific type and conforms protocol typically redundant – i'll explain why later. now, let's talk variables of type id<p>
, p
protocol, , why they're useful. type should read "an instance of class conforms p
."
to concretize discussion follows, let's define protocol:
@protocol adder - (nsinteger)add:(nsinteger)a to:(nsinteger)b; @end
i cannot see how variable can conform protocol.
this 1 easy. variable conforms objective-c protocol when represents instance of class implements of required methods in protocol.
@interface abacus : nsobject <adder> @end @implementation abacus - (nsinteger)add:(nsinteger)a to:(nsinteger)b { return + b; } - (nsinteger)beadcount { return 91; } @end
given abacus
class, could, of course, create new abacus
:
abacus *a = [[abacus alloc] init]; nslog(@"%ld", (long)[a add:5 to:6]); // 11 nslog(@"%ld", (long)[a beadcount]); // 91
but declare a
of type id<adder
. remember, means type of a
"an instance of class conforms adder
."
id<adder> = [[abacus alloc] init]; nslog(@"%ld", (long)[a add:5 to:6]); // 11 nslog(@"%ld", (long)[a beadcount]); // compile error: no known instance method selector 'beadcount'
the compiler complains because said type of a
is class conforms adder
, , in adder
protocol method named beadcount
.
what purpose of declaring variable conform [a protocol]?
the purpose information hiding. when want class conforms adder
, don't need care actual class – you id<adder>
. imagine abacus
system class, , you've written following code:
- (abacus *)getadder { return [[abacus alloc] init]; } - (void)dowork { abacus *a = [self getadder]; // lots of adding... }
then, in ios 42, apple comes new innovation – the calculator
class! friends tell calculator
adds 2 numbers more twice fast abacus
, , cool kids using it! decide refactor code, realize not have change return type of getadder
, types of variables assign return value of getadder
! lame. if had done instead:
- (id<adder>)getadder { return [[abacus alloc] init]; } - (void)dowork { id<adder> *a = [self getadder]; // lots of adding... }
now, when want migrate calculator
, need change body of getadder
return [[calculator alloc] init]
, you're done! 1 line. rest of code stays same. in case, have hidden true type of instance returned getadder
rest of code. information hiding makes refactoring easier.
lastly, promised explain why abacus <adder> *a = ...
redundant. you're saying here "a
instance of abacus
conforms adder
." (and compiler) know abacus
conforms adder
– it's right there in interface declaration! rmaddy points out, there cases want talk instance either given class, or subclass thereof, , specify conforms protocol, situations rare, , specifying both class , protocol conformance unneeded.
for more information, check out apple's working protcols guide.
Comments
Post a Comment