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