Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Well, I'm not a whole lot closer to knowing what the algorithm is, but I now have some idea of what it's <em>not</em> doing. I had a bit of time last night to whip up a test program to compare the methods and the results were rather surprising.</p> <p>The fastest method was pre-converting the point to window coordinates and then converting to each target view. What was surprising was <em>how much</em> faster it was: about 25-27 times faster! And on top of that, doing a two-stage conversion each time (first to window coordinates and then a separate call to convert to the target view) was still more than 10 times faster than a single call to <code>convertPoint:fromView:</code> with a non-nil view argument. I really cannot account for this. I might have expected one method to be up to twice as fast, but it really shouldn't be faster to do two conversions than to do one directly! (I tried the tests in various orders as well, to make sure that wasn't affecting the timings.)</p> <p>Here are the results (for 1 million conversions, run on an iPad 1, iOS 4.3.3):</p> <pre><code>convert from window point: 0.204297 two-step convert through window coordinates: 0.390832 convert from subview point: 5.020129 </code></pre> <p>I'll post the code below for review, but if these results are correct, my only guess is that the conversion code is highly optimized for converting to and from window/screen coordinates and that it uses some (much slower) method to convert directly between two view coordinate systems when given a non-nil view argument. Perhaps there are conditions where the disparity is not so great (such as when there are non-identity transformations involved), but for what I expect is the common case, it seems like it would be a whole lot better for it to do the two-step conversion first to window coordinates and then to the other view.</p> <p>Again, there are probably few circumstances where this will have a noticeable affect on a program, but it's something to keep in mind if you ever have to make a lot of repeated calls to <code>convertPoint:toView:</code> or <code>convertPoint:fromView:</code> .</p> <p>Here's my code, if anyone cares to check it over for errors or run it themselves:</p> <pre><code>@implementation TestConvertPointViewController - (NSTimeInterval) timeForBlock:(void (^)())block { CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); block(); return CFAbsoluteTimeGetCurrent() - startTime; } - (void) millionTimes:(void (^)(NSUInteger))block { for (NSUInteger i = 0; i &lt; 1000000; i++) { block(i); } } - (void)loadView { UIView* rootView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; UIView* subview = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 250, 500)]; UIView* subSubview = [[UIView alloc] initWithFrame:CGRectMake(20, 10, 130, 190)]; UIView* subSubSubview = [[UIView alloc] initWithFrame:CGRectMake(50, 10, 50, 100)]; [subSubview addSubview:subSubSubview]; [subview addSubview:subSubview]; [rootView addSubview:subview]; self.view = rootView; } - (void)test { UIView* subview = [[self.view subviews] objectAtIndex:0]; UIView* subSubview = [[subview subviews] objectAtIndex:0]; UIView* subSubSubview = [[subSubview subviews] objectAtIndex:0]; CGPoint testPoint = CGPointMake(10.0, 30.0); NSTimeInterval time; time = [self timeForBlock:^{ [self millionTimes: ^(NSUInteger i){ [subSubSubview convertPoint:testPoint fromView:nil]; } ]; } ]; NSLog(@"convert from window point: %f", time); time = [self timeForBlock:^{ [self millionTimes: ^(NSUInteger i){ CGPoint rootPoint = [subview convertPoint:testPoint toView:nil]; [subSubSubview convertPoint:rootPoint fromView:nil]; } ]; } ]; NSLog(@"two-step convert through window coordinates: %f", time); time = [self timeForBlock:^{ [self millionTimes: ^(NSUInteger i){ [subSubSubview convertPoint:testPoint fromView:subview]; } ]; } ]; NSLog(@"convert from subview point: %f", time); } - (void)viewDidLoad { [super viewDidLoad]; [self test]; } @end </code></pre> <p>I also tested it with 100 sub-sub-subviews, choosing a different one each time through, in case there was some caching going on, and the only difference could probably be accounted for in the extra overhead of the array lookups.</p> <p>So, I'm not sure what to make of this, but I know how I'm going to use <code>convertPoint:fromView:</code> in the future! :-)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload