cocoansmutabledictionarynsfont

Cocoa NSFont 'leading' attribute build error


In an AudioUnit plugin, I'm using NSFont.

NSFontManager* fontManager = [NSFontManager sharedFontManager];
NSFont* nativefont = [fontManager fontWithFamily:[NSString stringWithCString: fontFamilyName.c_str() encoding: NSUTF8StringEncoding ] traits:fontTraits weight:5 size:fontSize ];

NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment : NSTextAlignmentLeft];

NSMutableDictionary* native2 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                nativefont, NSFontAttributeName,
                    style, NSParagraphStyleAttributeName,
                    nil];

// .. later
void someFunction(NSMutableDictionary* native2)
{   
    float lineGap = [native2[NSFontAttributeName] leading];

Compiler says (about last line): assigning to 'float' from incompatible type 'NSCollectionLayoutSpacing * _Nullable'

NOTE: This has only failed recently since switching to Xcode 11.1, on an older version of XCode it built OK. Any help appreciated.


Solution

  • In your code, the expression native2[NSFontAttributeName] is of unknown type, and therefore of type id. The compiler will let you send an object of type id any message without complaint, but it has no context for determining the type of the message's return value.

    You want to get the leading property of NSFont, but the compiler is just picking any leading property selector at random and I'm guessing it has ended up choosing the leading property of NSCollectionLayoutEdgeSpacing which has a return type of NSCollectionLayoutSpacing not float.

    I suspect that casting the expression [(NSFont*)(native2[NSFontAttributeName]) leading] would do the trick, but if I were writing this code I'd simply refer to the original (typed) object, since you already have it:

    float lineGap = nativefont.leading;