You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

-[NSObject valueForKey:]及Swift对应方法何时不返回NSObject?

Answers to Your KVC Questions

1. When does - [NSObject valueForKey:] not return an NSObject type in Objective-C?

In most standard KVC scenarios, valueForKey: will either return an instance of an NSObject subclass (like NSNumber, NSString, etc.) or nil. But there are a couple of edge cases where it might not:

  • Unbridged Core Foundation objects in Manual Retain/Release (MRC)
    If you're working in MRC and a custom getter for your key returns a raw Core Foundation object (e.g., CFStringRef) without bridging it to its Foundation counterpart (e.g., NSString *), then valueForKey: will hand back that CF object. Core Foundation objects aren't subclasses of NSObject—even though many have toll-free bridging to Foundation classes. Note that this doesn't happen in ARC, which automatically handles bridging between CF and Foundation types.

  • Custom overrides of valueForKey: that violate KVC rules
    If a developer manually overrides valueForKey: to return a scalar type (like int, float, or BOOL) directly instead of wrapping it in an NSNumber/NSValue, then the return value won't be an NSObject. This is strongly discouraged though, as it breaks the KVC contract and can lead to unexpected crashes or behavior.

2. In Swift, does NSObject.value(forKey:) ever return something that's not an NSObject?

Absolutely—since Swift's value(forKey:) is typed to return Any?, it can return non-NSObject types, and this happens fairly commonly in practice:

  • Unboxed Swift value types from Objective-C scalars
    When you use KVC to access an Objective-C scalar property (like int, float, BOOL, or CGRect), Swift automatically unboxes the underlying NSNumber/NSValue into the corresponding Swift value type. For example:

    class Person: NSObject {
        @objc var age: Int = 30
        @objc var isStudent: Bool = true
    }
    let person = Person()
    let ageValue = person.value(forKey: "age") // Type is Int, not NSNumber
    let studentStatus = person.value(forKey: "isStudent") // Type is Bool, not NSNumber
    

    These Swift value types (structs like Int, Bool, CGRect) aren't subclasses of NSObject.

  • @objc-marked Swift value type properties
    If you define a Swift value type property in an NSObject subclass and mark it with @objc, using value(forKey:) will return the raw Swift struct instead of wrapping it in an NSValue. For example:

    class Shape: NSObject {
        @objc var frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
    }
    let shape = Shape()
    let frameValue = shape.value(forKey: "frame") // Type is CGRect, not NSValue
    
  • Unbridged Core Foundation objects (rare)
    In some edge cases, you might get a raw Core Foundation object back (e.g., certain specialized CF types that don't auto-bridge cleanly) which isn't an NSObject subclass. This is uncommon though, as Swift usually handles CF-Foundation bridging automatically.


内容的提问来源于stack exchange,提问作者Kamchatka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:02:01