I recently ran into a Foundation compatibility difference on non-Darwin platforms: NSObject itself does not conform to CVarArg in swift-corelibs-foundation, so NSObject subclasses that do not have their own explicit conformance cannot be passed to %@ formatting APIs.
For example, this works on Darwin Foundation:
import Foundation
let value = NSAttributedString(string: "hello")
let result = NSString(format: "%@", value)
print(result)
but currently fails to compile on Linux with:
error: argument type 'NSAttributedString' does not conform to expected type 'CVarArg'
There was a previous related discussion and implementation for NSString / String:
- Previous forum thread: CVarArg support for NSString and String
- Previous swift-corelibs-foundation PR: Added CVarArg support to NSString and String by Molanda · Pull Request #2821 · swiftlang/swift-corelibs-foundation · GitHub
- Related Swift PR for
_CVarArgObject: Added protocol to support CVarArg objects that need to be retained by Molanda · Pull Request #32311 · swiftlang/swift · GitHub
That fixed NSString and String, but the broader NSObject subclass case still appears to be missing.
I opened an issue and PR here:
- Issue: make NSObject implement CVarArg protocol · Issue #5487 · swiftlang/swift-corelibs-foundation · GitHub
- PR: Make NSObject conform to CVarArg by Kyle-Ye · Pull Request #5488 · swiftlang/swift-corelibs-foundation · GitHub
The proposed fix is to make NSObject conform to CVarArg, so subclasses such as NSAttributedString can be passed as %@ arguments consistently on non-Darwin Foundation. This also makes the existing explicit NSString: CVarArg conformance redundant, since NSString inherits from NSObject.
The implementation follows the same object vararg encoding approach:
extension NSObject: CVarArg {
@inlinable // c-abi
public var _cVarArgEncoding: [Int] {
#if _runtime(_ObjC) // Note: I removed this in the final PR
_autorelease(self)
#endif
return _encodeBitsAsWords(self)
}
}
A few questions I would like feedback on:
- Does putting the conformance on
NSObjectmatch the intended Foundation model for non-Darwin platforms? - Are there any ABI, source compatibility, or behavioral concerns with moving this from
NSStringtoNSObject?
Thanks!