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

Retrieving ETA (estimated time of arrival) with Google Distance Matrix API and public transit as transport mode -

javascript - Confirm a form & display message if form is valid with JQuery -

ionic framework - Meteor - Error: Failed to execute 'insertBefore' on 'Node' -