SudzC ARC version - objc_msgSend call causes EXC_BAD_ACCESS using 64-bit architecture

前端 未结 1 1413
时光说笑
时光说笑 2020-12-04 22:35

Edit - I\'ve tracked the below issue to a 64-bit vs 32-bit architecture issue... see my posted answer for how I resolved

I\'ve used SudzC to genera

相关标签:
1条回答
  • 2020-12-04 22:54

    OK - so after more hair-pulling and research, it finally dawned on me that it might be a 64-bit vs 32-bit issue. This was the first app I was working on since upgrading to the new Xcode. I went to Build Settings and changed the Architectures from "Standard architectures (including 64-bit) (armv7, armv7s, arm64)" to "Standard architectures (armv7, armv7s)". This fixed the issue!

    I then went back and researched why this was happening. I found this Apple 64-bit transition guide: https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html

    The document mentions the following:

    Dispatch Objective-C Messages Using the Method Function’s Prototype An exception to the casting rule described above is when you are calling the objc_msgSend function or any other similar functions in the Objective-C runtime that send messages. Although the prototype for the message functions has a variadic form, the method function that is called by the Objective-C runtime does not share the same prototype. The Objective-C runtime directly dispatches to the function that implements the method, so the calling conventions are mismatched, as described previously. Therefore you must cast the objc_msgSend function to a prototype that matches the method function being called.

    Listing 2-14 shows the proper form for dispatching a message to an object using the low-level message functions. In this example, the doSomething: method takes a single parameter and does not have a variadic form. It casts the objc_msgSend function using the prototype of the method function. Note that a method function always takes an id variable and a selector as its first two parameters. After the objc_msgSend function is cast to a function pointer, the call is dispatched through that same function pointer.

    Using this information, I changed the below line:

    objc_msgSend(self.handler, self.action, self.value);

    to:

    id (*response)(id, SEL, id) = (id (*)(id, SEL, id)) objc_msgSend;
    response(self.handler, self.action, output);
    

    And all is working!

    Hopefully this will help someone else...

    0 讨论(0)
提交回复
热议问题