@available guard与弱链接编译失败:NSCursor.columnResizeCursor属性未找到
解决NSCursor.columnResizeCursor编译报错问题
你遇到的问题核心是编译时SDK版本不支持该属性:弱链接AppKit只能处理运行时符号缺失的情况,但14.0 SDK的头文件里根本没有columnResizeCursor这个属性的定义,编译器完全不认识它,所以编译阶段直接报错,和弱链接没关系。
下面是几种可行的解决办法:
方法一:用运行时API动态获取属性
绕开编译阶段的检查,通过Objective-C运行时API直接获取这个光标对象:
// main.m #include <AppKit/AppKit.h> #include <objc/runtime.h> int main() { if (@available(macOS 15.0, *)) { // 动态获取columnResizeCursor属性 NSCursor *cursor = objc_getProperty(objc_getClass("NSCursor"), SEL_getUid("columnResizeCursor"), 0, YES); [cursor set]; } else { [NSCursor.resizeLeftRightCursor set]; } }
编译命令保持不变:clang -mmacos-version-min=10.14 -weak_framework AppKit main.m
方法二:通过performSelector调用类方法
类属性本质是类方法,所以可以用performSelector来间接调用:
// main.m #include <AppKit/AppKit.h> #pragma clang diagnostic ignored "-Warc-performSelector-leaks" int main() { if (@available(macOS 15.0, *)) { NSCursor *cursor = [(id)NSCursor performSelector:NSSelectorFromString(@"columnResizeCursor")]; [cursor set]; } else { [NSCursor.resizeLeftRightCursor set]; } }
添加#pragma是为了消除编译器关于performSelector的内存泄漏警告。
方法三:使用更高版本SDK编译(推荐)
如果能拿到macOS 15.0及以上的SDK,直接用它编译,同时保留最低系统版本限制:
clang -mmacos-version-min=10.14 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk -framework AppKit main.m
这种方式最简洁,编译器能识别columnResizeCursor,@available会自动保证旧系统运行时走else分支,无需额外的运行时技巧。
内容的提问来源于stack exchange,提问作者Jason1923
相关产品推荐
相关产品推荐

