Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to track touches in a consistent way between touchesBegan: and touchesEnded:?

In some maintenance of some multitouch "drawing on screen" code, I met a bug relative to how references to touches instances should be set between touchesBegan:withEvent:, touchesMoved:withEvent: and touchesEnded:withEvent:.

The code uses a NSDictionary instance to store references of touches in touchesBegan:withEvent:, as follow :

for (UITouch *touch in touches]) {
    NSValue *touchValue = [NSValue valueWithPointer:touch];
    NSString *key = [NSString stringWithFormat:@"%@", touchValue];
    [myTouches setValue:squiggle forKey:key];
}

And retrieves them in touchesEnded:withEvent: this way:

for (UITouch *touch in touches) {
    NSValue *touchValue = [NSValue valueWithPointer:touch];
    NSString *key = [NSString stringWithFormat:@"%@", touchValue];
    NSObject *valueFromDictionary = [myTouches valueForKey:key];
    [myTouches removeObjectForKey:key];
}

In this last bit of code, valueFromDictionary happens to occasionally be nil, as the key is not known by the dictionary. By occasionnally, I mean about 1% of the time.

Now the context is set, my questions are:

  1. Any idea why this code is buggy? I'm not sure why it doesn't work, especially because of the very low frequency of errors

  2. Some doc from Apple states it's a good idea to use addresses of the UITouch objects as keys : but it means using NSValue* objects rather than NSString* objects ( and consequently using CFDictionaryRef rather than NSDictionary because of the fact UITouch doesn't implement the copying protocol). How come storing a NSString representation of the address rather than the NSValue itself can not be an easy solution to be able to use NSDictionary? Update: Apple has updated the page and removed the example of storing a UITouch via a NSString and just mentions the not-object-at-all CFDictionaryRef solution.

I'm afraid I'm far from C and pointers stuff and need help to understand the reason there's a bug in this code.

like image 869
Dirty Henry Avatar asked Sep 09 '11 10:09

Dirty Henry


1 Answers

You can use hash of UITouch property for both ObjC and Swift. It is the same for the same touch across multiple events (Up, Down, Move, etc). It is an Int but you can convert it to String

like image 187
Zhao Avatar answered Sep 17 '22 13:09

Zhao