Re: Voice Over Performance for Complex Custom View
Re: Voice Over Performance for Complex Custom View
- Subject: Re: Voice Over Performance for Complex Custom View
- From: Xiang Cao <email@hidden>
- Date: Thu, 17 Sep 2009 14:06:12 -0700
- Thread-topic: Voice Over Performance for Complex Custom View
Thanks for the explanation. I think the only way for me to improve the
performance is to create and retain the unignored children list for the
first time. So every time when voice over ask for children, I can just
return a list of prepared unignored children instead of calling
"NSAccessibilityUnignoredChildren" to do this everytime. With the help of
Instruments test tool, I think the NSAccessibilityUnignoredChildren is the
most time consuming part because of it's recursive nature and my huge UI
structure.
My question is: what does NSAccessibilityUnignoredChildren do? Does it only
return the unignored children or it also return unignored grandchildren? In
another word, when voice over ask for children, does it mean all the
unignored children below the current level? Or it means the unignored
children from the next level only?
Thanks
On 9/17/09 11:25 AM, "James Dempsey" <email@hidden> wrote:
> Xiang,
>
>> My question is when they ask about children's count, subarray or
>> index, do they mean their unignored children or the direct children?
>
> The methods deal with unignored children. You should never return an
> ignored element from any NSAccessibility method.
>
> If you already have the children arrays built, and you are not
> creating new accessibility objects every time, I would not expect you
> to see much performance improvement from these three methods because
> your implementations are essentially doing what AppKit does by default
> anyway. Since you are not creating the children new every time they
> are asked for, there won't be much savings.
>
> The methods tend to improve performance most when you have enough
> internal information to avoid the array operation. For instance, if
> your faux object stored its child index, such that - (NSUInteger)
> accessibilityIndexOfChild:(id)child was not an array lookup, but you
> could just pull the index out of the child and return it, you would
> probably see a performance boost.
>
> Note that another reason why the methods may not be working is that
> accessibilityArrayAttributeCount: does not call super, so if VoiceOver
> checks to see the size of anything but children, it will be told there
> are zero items.
>
> -James
>
> On Sep 17, 2009, at 10:38 AM, Xiang Cao wrote:
>
>> Thanks for the hint.
>>
>> I changed the hash to return the pointer of real view instead of
>> recursive.
>> But the performance does not become better. To answer your question,
>> my real
>> GUI object are in C++, not Object C. That's why I have to create a
>> fake
>> structure for accessibility.
>>
>> About the three new functions, I still cannot get it work. My
>> question is
>> when they ask about children's count, subarray or index, do they
>> mean their
>> unignored children or the direct children? You mentioned for the sub
>> array
>> you have to always return the unignored children, but what about the
>> count
>> and the index? What are the target objects they are asking?
>>
>> My full code of that three functions:
>>
>> - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
>> {
>> if([attribute isEqualToString:NSAccessibilityChildrenAttribute])
>> {
>> if(mChildren) return [mChildren count]; else return 0;
>> }else 0;
>> }
>>
>> - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute
>> index:(NSUInteger)index maxCount:(NSUInteger)maxCount
>> {
>> if([attribute isEqualToString:NSAccessibilityChildrenAttribute])
>> {
>> if(index+maxCount>[mChildren count]) maxCount = [mChildren
>> count] -
>> index;
>> NSRange range = NSMakeRange(index, maxCount);
>> NSArray* subarray = [NSAccessibilityUnignoredChildren
>> (mChildren)
>> subarrayWithRange:range];
>> //I changed this from direct children's subarray to unigored
>> children's sub
>> array, there is no error anymore, but it still does not work properly.
>> NSLog(@"subarray count %d", [subarray count]);
>> return subarray;
>> }else return [super accessibilityArrayAttributeCount:attribute];
>> }
>>
>> - (NSUInteger)accessibilityIndexOfChild:(id)child
>> {
>> DFW_Accessibility* dfwchild = (DFW_Accessibility*)child;
>>
>> if(dfwchild->mParent && dfwchild->mParent->mChildren)
>> {
>> NSUInteger index = [dfwchild->mParent->mChildren
>> indexOfObject:child];
>> if(index == NSNotFound)
>> {
>> NSLog(@"NSNotFound");
>> return NSNotFound;
>> }else NSLog(@"child index %d", index);
>> return index;
>> }else
>> {
>> return NSNotFound;
>> }
>> }
>>
>> By the way, I have filed the bug about the double speak.
>>
>> Do you know any performance checking tool beside shark on snow
>> leopard which
>> can check which part of code is consuming the time? Because shark
>> does not
>> work on our app under snow leopard.
>>
>> Thanks.
>>
>>
>> On 9/16/09 5:36 PM, "Mike Engber" <email@hidden> wrote:
>>
>>>
>>> On Sep 16, 2009, at 4:11 PM, Xiang Cao wrote:
>>>
>>>> Thanks for the reply.
>>>>
>>>> My isEqual is implemented as the following:
>>>>
>>>> - (BOOL)isEqual:(id)object {
>>>> if ([object isKindOfClass:[DFW_Accessibility self]]) {
>>>> DFW_Accessibility* other = object;
>>>> return mTView == other->mTView;
>>>> } else {
>>>> return NO;
>>>> }
>>>> }
>>>>
>>>> - (unsigned)hash {
>>>> return [mRole hash] + [mParent hash]; //mRole is NSString* and
>>>> mParent
>>>> is another DFW_Accessibility object
>>>> }
>>>>
>>>> Because each of my custom access object has an linked Tview pointer
>>>> which
>>>> points to one of the real element in our GUI library. I think it
>>>> should be
>>>> correct to compare their pointer to see if they are the same
>>>> accessibility
>>>> object. For hash, I'm not sure if I'm doing it correctly or not.
>>>
>>> You hash function will return the same value for all siblings with
>>> the
>>> same role. While this is OK since equal object will hash the same, it
>>> could be improved.
>>>
>>> Plus it will be fairly expensive since it recurs up the hierarchy
>>> calling hash on all its ancestors.
>>>
>>> I suggest simply returning mTView (i.e. the address).
>>>
>>>> I forgot to mention. I didn't generate all the children everytime on
>>>> the
>>>> fly. They are allocated only when children attributes are asked for
>>>> the
>>>> first time. Then the array is retained as a member variable for
>>>> later use. I
>>>> did this to improve the performance, but it's still a little slow.
>>>
>>> Are the "real elements" in your GUI libray ObjC objects? If so, it
>>> would be cheapest to just make those classes implment the
>>> accessibility protocol.
>>>
>>> When I don't have ObjC object I can accessorize, I generally create
>>> UI
>>> Elements on the fly and it performs well enough. One advantage of
>>> this
>>> approach is the UI Elements are never out of sync with the actual UI.
>>> I guess if your hierarchy is big enough, all the allocations could be
>>> slowing you down. You should measure and test.
>>>
>>> As for your original problem:
>>>> But I saw errors from console said like: !!! Failed to find child 2
>>>>>
>>>> (index 2) for AX specifier: <NSWindow: 0x21eb1e90>{32}.
>>>
>>> It seems like you're returning a ui element that's the second child
>>> of
>>> the window's third child. But, somehow later when we go to use this
>>> ui
>>> element its parent is reporting that it has no children.
>>>
>>> Did you implement all three methods:
>>> (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
>>> - (NSArray *)accessibilityArrayAttributeValues:(NSString *)
>>> attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
>>> - (NSUInteger)accessibilityIndexOfChild:(id)child
>>>
>>> Your email only showed code for the last method.
>>>
>>> If you did implement all these methods, I'm going to guess that the
>>> problem is accessibilityArrayAttributeValues is returning an empty
>>> array when passed a maxCount of one.
>>>
>>> -ME
>>>
>>
>
> --------------------------------------------------
> James Dempsey
> AppKit Engineering
> Apple
> email@hidden
>
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Accessibility-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden