On 22 Jun 2015, at 09:12, Quincey Morris < email@hidden> wrote:
On Jun 21, 2015, at 17:52 , Roland King < email@hidden> wrote:
But this isn’t a framework weak link - it should just be a symbol weak link. That symbol has the availability macro on it, so it should be in the binary as weak as long as the target is, as Scott said earlier, set to pre-10.7. But if the deployment target is 10.7, that information should be in the binary as well and it should fail to load at all, usually with a very cryptic error message. Not making much sense.
Looking back at the error message:
Dyld Error Message: Symbol not found: _OBJC_CLASS_$_NSDataDetector Referenced from: /Applications/Mellel.app/Contents/MacOS/MyApp Expected in: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
then, yes, it looks like a weak *class* link problem, not a weak *framework* link problem.
However, my theory is still the same. My theory is that Xcode [hypothetically] knows that automatic weak linking of class symbols wasn’t available prior to 10.6.8 [hypothetically], and so a deployment target of 10.6.0 will set the unresolved symbol to require a strong link**. Changing the deployment target to 10.6.8 [hypothetically] will cause Xcode [hypothetically] to emit a weak link for the class symbol.
Alternatively, there may be a linker command that forces it to make the _OBJC_CLASS_$_NSDataDetector symbol a weak reference at link time. That might solve it with the existing code and deployment target [hypothetically].
I freely admit that I know very little about this stuff. My intended contribution to the conversation was to remind everyone that the “modern” weak-linking mechanism that made everyone’s life easier was *not* introduced on a major OS X version boundary, IIRC.
Pretty sure the class availability macro has worked since 10.2.
I went and built one .. which was hard as my brain appears to have swiftified. Built a 2-architecture, i386, x86_64 and deployed back to 10.6 and then 10.7.
Here’s 10.6
Rols-MacBook-Pro-Retina:Debug rols$ nm -mg TestWeakLink -arch i386|grep NSDataDetector (undefined) external .objc_class_name_NSDataDetector (from Foundation)
Rols-MacBook-Pro-Retina:Debug rols$ nm -mg TestWeakLink -arch x86_64|grep NSDataDetector (undefined) weak external _OBJC_CLASS_$_NSDataDetector (from Foundation)
and here’s 10.7
Rols-MacBook-Pro-Retina:Debug rols$ nm -mg TestWeakLink -arch i386|grep NSDataDetector (undefined) external .objc_class_name_NSDataDetector (from Foundation)
Rols-MacBook-Pro-Retina:Debug rols$ nm -mg TestWeakLink -arch x86_64|grep NSDataDetector (undefined) external _OBJC_CLASS_$_NSDataDetector (from Foundation)
So the i386 version didn’t change at all, so that may explain why the i386 one keeps working. The x86_64 architecture indeed does give the symbol as weak built for 10.6 but not for 10.7, which is what I’d hope would happen. That lends credence to the suggestion the code was simply built with the wrong deployment target.
Just for reference this was built on Xcode 7 against the 10.10 SDK, but it’s 2 lines of code so the tool probably doesn’t matter very much.
|