Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not use KVC from an Objective-C object to a Swift Property?

My team has decided that new files should be written in swift, and I am seeing an odd problem with using KVC in an Objective-C object to set a property on a Swift object.

My Objective-C sets a property like so: [textObject setValue:0.0 forKey:@"fontSize"]

My Swift object (textObject) has a custom setter/getter for this property.

   var fontSize: CGFloat? {
      get {
         return internalTextGraphic?.fontSize 
      }
      set {
            internalTextGraphic?.fontSize = newValue
      }
   }

However, if I set a breakpoint in the set, it never gets hit.

I have Objective-C objects that also get this same call, and I just implement -setFontSize, and the execution enters properly.

Why can't I seem to get into my set method through -setValueForKey? I have 100% confirmed the textObject is exists and is the correct type.

EDIT:
Martin R is correct, I had to make the type a non-optional. This is my working code:

   var fontSize: CGFloat {
      get {
         var retFontSize: CGFloat = 0.0
         if let fontSize = internalTextGraphic?.fontSize {
            retFontSize = fontSize
         }
         return retFontSize
      }
      set {
         if let textGraphic = internalTextGraphic {
            textGraphic.fontSize = newValue
         }
      }
   }
like image 894
A O Avatar asked Mar 03 '16 21:03

A O


People also ask

What is KVC in Swift?

According to Apple: Key-value coding is a mechanism for accessing an object's properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables.

What is KVC and KVO?

KVO and KVC or Key-Value Observing and Key-Value Coding are mechanisms originally built and provided by Objective-C that allows us to locate and interact with the underlying properties of a class that inherits NSObject at runtime.

What is key-value coding?

Key-value coding is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface.


1 Answers

The reason is that a Swift optional struct or enum (in your case CGFloat?) is not representable in Objective-C (and you won't see that property in the generated "Project-Swift.h" header file). That becomes more obvious if you mark the property explicitly with @objc, then you'll get the error message

error: property cannot be marked @objc because its type cannot be represented in Objective-C

If you change the property type to the non-optional CGFloat then KVC works as expected. It would also work with an optional class type, such as NSNumber?.

like image 127
Martin R Avatar answered Nov 14 '22 21:11

Martin R