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

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -