'Old c++/objective-c++ project no longer complies code that stores UIKit objects in stl containers "Cast of a non-Objective-C pointer type ... UITouch"

So I built this engine designed to be cross platform. I have a TON of custom handling of multi-touch long past what UIKit does to aid in the game the engine is for.

To do this I introduced the design of a PlatformTouchManager (this c++ class has engine structs handling everything and turning it into plain old c structs in vectors.

Then for each platform there is a class that is a subclass an objective-c++ class iOSMultiTouch: public PlatformTouchManager { that will handle the UIKit objects and call and modify things on the superclass to keep its engine-level idea of multitouch state correct.

Now in this PlatformTouchManager (objective-c++) I have quite a bit of code that puts UIKit objective-c objects into STL containers such as

std::set<std::shared_ptr<UITouch*>> downSet;
std::vector<std::shared_ptr<UITouch*>> fingerList;
void iOSMultiTouch::touchesDown(NSSet* set) {
    for (UITouch* t in set) {
        std::shared_ptr<UITouch*> sptr = std::make_shared<UITouch*>(t);
        if (downSet.find(sptr) == downSet.end()) {
            downSet.insert(sptr);
        }
    }
}

I dont know whether this is a bad idea per say but it has worked for years of this project compiling.

Now all of a sudden I am getting this error /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/memory:2684:27: Cast of a non-Objective-C pointer type 'typename _CompressedPair::_Base2 *' (aka '__compressed_pair_elem<UITouch *__strong, 1> *') to 'UITouch *__strong *' is disallowed with ARC And its blame goes down MANY stacks (into STL and out into my code) into this line std::shared_ptr<UITouch*> sptr = std::make_shared<UITouch*>(t);

Is there some sort of annotation I need to be putting in to help this code work and compile? Perhaps this is entirely a bad idea to do it this way?

I think the reason I did the class this way was that I thought I needed the class defined in objective-c++ code to be a c++ class to fit in and that that c++ class object in the header couldn't use objective-c things.



Solution 1:[1]

It is telling you that you have a pointer to __compressed_pair_elem which is not an Objective-C object, and cast it to a pointer to an Objective-C object, that is not allowed by ARC, it doesn't know how to treat the result.

The correct type for using in the C++ code is id:

std::set<std::shared_ptr<id __strong>> downSet;
std::vector<std::shared_ptr<id __strong>> fingerList;
void iOSMultiTouch::touchesDown(NSSet* set) {
    for (UITouch* t in set) {
        std::shared_ptr<id __strong> sptr = std::make_shared<id __strong>(t);
        if (downSet.find(sptr) == downSet.end()) {
            downSet.insert(sptr);
        }
    }
}

PS.
Not sure if I am right, I do not have access to Xcode right now.

  1. for (UITouch* t in set) may be incorrect and should be for (UITouch* t : set).
  2. __strong may be odd in the declarations and may be omitted.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 273K