-[NSObject valueForKey:]及Swift对应方法何时不返回NSObject?
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 *), thenvalueForKey:will hand back that CF object. Core Foundation objects aren't subclasses ofNSObject—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 overridesvalueForKey:to return a scalar type (likeint,float, orBOOL) directly instead of wrapping it in anNSNumber/NSValue, then the return value won't be anNSObject. 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 (likeint,float,BOOL, orCGRect), Swift automatically unboxes the underlyingNSNumber/NSValueinto 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 NSNumberThese Swift value types (structs like
Int,Bool,CGRect) aren't subclasses ofNSObject.@objc-marked Swift value type properties
If you define a Swift value type property in anNSObjectsubclass and mark it with@objc, usingvalue(forKey:)will return the raw Swift struct instead of wrapping it in anNSValue. 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 NSValueUnbridged 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 anNSObjectsubclass. This is uncommon though, as Swift usually handles CF-Foundation bridging automatically.
内容的提问来源于stack exchange,提问作者Kamchatka

