View Issue Details

IDProjectCategoryView StatusLast Update
0035994FPCPackagespublic2019-08-31 13:45
ReporterZoë PetersonAssigned ToJonas Maebe 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product VersionProduct Build 
Target VersionFixed in Version3.2.0 
Summary0035994: CocoaInt: NSMutableDictionary is difficult to use with new headers
DescriptionWith the new Cocoa headers, instantiating an NSDictionary or NSMutableDictionary no longer finds the correct symbols, and gives errors about NSArray that don't make any sense in context.

The attached project compiles correctly in FPC 3.0.4 but fails with the current trunk (rev 42765)

var
  dict: NSDictionary;
  mDict: NSMutableDictionary;
begin
  dict := NSDictionary.dictionaryWithContentsOfFile(path);
  dict := NSDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
  dict := NSDictionary(NSDictionary.alloc).initWithContentsOfFile(path);

  dict := NSMutableDictionary.dictionaryWithContentsOfFile(path);
  mDict := NSMutableDictionary.dictionaryWithContentsOfFile(path); // ERROR: got "NSDictionary" expected "NSMutableDictionary"
  dict := NSMutableDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
  mDict := NSMutableDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
TagsNo tags attached.
Fixed in Revisionr42816, r42883
FPCOldBugId
FPCTarget3.2.0
Attached Files
  • nsdict_test.pp (891 bytes)
    {$MODE OBJFPC}
    {$MODESWITCH OBJECTIVEC1}
    
    program test;
    
    uses
      CocoaAll;
    
    var
      obj: NSObject;
      path: NSString;
      dict: NSDictionary;
      mDict: NSMutableDictionary;
    begin
      obj := NSObject.alloc.init;
    
      path := NSSTR('');
      dict := NSDictionary.dictionaryWithContentsOfFile(path);
      dict := NSDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
      dict := NSDictionary(NSDictionary.alloc).initWithContentsOfFile(path);
    
      dict := NSMutableDictionary.dictionaryWithContentsOfFile(path);
      mDict := NSMutableDictionary.dictionaryWithContentsOfFile(path); // ERROR: got "NSDictionary" expected "NSMutableDictionary"
      dict := NSMutableDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
      mDict := NSMutableDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
    
    end.
    nsdict_test.pp (891 bytes)

Activities

Zoë Peterson

2019-08-23 00:04

reporter  

nsdict_test.pp (891 bytes)
{$MODE OBJFPC}
{$MODESWITCH OBJECTIVEC1}

program test;

uses
  CocoaAll;

var
  obj: NSObject;
  path: NSString;
  dict: NSDictionary;
  mDict: NSMutableDictionary;
begin
  obj := NSObject.alloc.init;

  path := NSSTR('');
  dict := NSDictionary.dictionaryWithContentsOfFile(path);
  dict := NSDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
  dict := NSDictionary(NSDictionary.alloc).initWithContentsOfFile(path);

  dict := NSMutableDictionary.dictionaryWithContentsOfFile(path);
  mDict := NSMutableDictionary.dictionaryWithContentsOfFile(path); // ERROR: got "NSDictionary" expected "NSMutableDictionary"
  dict := NSMutableDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"
  mDict := NSMutableDictionary.alloc.initWithContentsOfFile(path); // ERROR: got "NSArray" expected "NSDictionary"

end.
nsdict_test.pp (891 bytes)

Jonas Maebe

2019-08-24 11:27

manager   ~0117817

Last edited: 2019-08-24 15:36

View 3 revisions

It's because this used to the be the declaration in the old Objective-C headers:
@interface NSArray (NSArrayCreation)
...
- (id)initWithContentsOfFile:(NSString *)path;


This is the one in current SDKs:
@interface NSArray<ObjectType> (NSArrayCreation)
...
- (nullable NSArray<ObjectType> *)initWithContentsOfFile:(NSString *)path;


The same goes for the initWithContentsOfFile declarations in other categories for other classes. I wonder how Objective-C compilers deal with this.

Jonas Maebe

2019-08-24 11:29

manager   ~0117818

Last edited: 2019-08-24 15:37

View 2 revisions

Ah, found it: http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-features

Ryan Joseph

2019-08-24 22:41

reporter   ~0117828

The compiler thinks "alloc" is returning NSObject and so one of the other category methods gets called instead of NSDictionary? What changed btw, was it the headers or something in the compiler? The 10.10 headers are 4+ years old now and I don't remember this being a problem until just recently.

Issue History

Date Modified Username Field Change
2019-08-23 00:04 Zoë Peterson New Issue
2019-08-23 00:04 Zoë Peterson File Added: nsdict_test.pp
2019-08-24 11:27 Jonas Maebe Note Added: 0117817
2019-08-24 11:28 Jonas Maebe Note Edited: 0117817 View Revisions
2019-08-24 11:29 Jonas Maebe Note Added: 0117818
2019-08-24 15:36 Jonas Maebe Note Edited: 0117817 View Revisions
2019-08-24 15:37 Jonas Maebe Note Edited: 0117818 View Revisions
2019-08-24 22:41 Ryan Joseph Note Added: 0117828
2019-08-25 17:24 Jonas Maebe Assigned To => Jonas Maebe
2019-08-25 17:24 Jonas Maebe Status new => resolved
2019-08-25 17:24 Jonas Maebe Resolution open => fixed
2019-08-25 17:24 Jonas Maebe Fixed in Version => 3.3.1
2019-08-25 17:24 Jonas Maebe Fixed in Revision => r42816
2019-08-25 17:24 Jonas Maebe FPCTarget => 3.2.0
2019-08-30 19:12 Zoë Peterson Status resolved => closed
2019-08-31 13:45 Jonas Maebe Fixed in Version 3.3.1 => 3.2.0
2019-08-31 13:45 Jonas Maebe Steps to Reproduce Updated View Revisions
2019-08-31 13:45 Jonas Maebe Fixed in Revision r42816 => r42816, r42883