Setting animationDidStopSelector: on UIView's

2019-06-23 09:33发布

问题:

I think I've been doing this wrong for the past year and a half of my iPhone development experience... I could use some knowledgeable clarification please!

As you may or may not know, UIView properties can be animated quite easily using the beginAnimations:forContext: method, and wrap it up with a commitAnimations call.

You can also set an animation delegate to perform actions when certain parts of the animation occur, such as starting, finishing etc.

I've been using UIView animations in my code for a long time and never had any serious problems, but I've just come across a section of the docs that I must have missed.

The documentation for UIView's setAnimationDidStopSelector: states that any selector passed into this method should be of the form:

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;

I haven't been doing that at all. I've been setting plain old doThis and doThat type selectors that take no parameters.

Is what I've been doing acceptable? Should I rewrite all my code to use the documented form? Or is that form simply for convenience if I need to know whether or not the animation completed before being stopped or needed to pass some context specific data to the method?

回答1:

It's acceptable.


In assembly level, calling an Objective-C method

id something = [obj method:arg0 and:arg1 also:arg2 asWellAs:arg3];

will look like (not actual ARM code):

load  r0      <- obj
load  r1      <- @selector(method:and:also:asWellAs:)
load  r2      <- arg0
load  r3      <- arg1
load  [sp, 0] <- arg2
load  [sp, 4] <- arg3
call          objc_msgSend
store r0      -> something

where objc_msgSend will keep all the registers, find -method:and:also:asWellAs:, and jump to it. Within -method:… the compiler will associate the parameters back to the registers, i.e.

store r0        -> self
store r1        -> _cmd
store r2        -> param0
store r3        -> param1
store [sp, ?]   -> param2
store [sp, ?+4] -> param3
// rest of execution

Now what happen if your method is only -doThis or -doThat?

store r0        -> self
store r1        -> _cmd
// rest of execution

There will be no parameters so the registers r2, r3 and the stack values are free to override. In the other words, the compiler/runtime will simply ignore the extra parameters.

Problems will arise only if you take up too many parameters.