Recent

Author Topic: How to create an NSArray  (Read 7015 times)

LazProgger

  • Full Member
  • ***
  • Posts: 103
How to create an NSArray
« on: May 16, 2016, 06:32:35 pm »
I need to create an array of type NSArray containing a list of files on Mac OS X.

However, I cannot find any constructor or other method to create such an array. I have searched the web and found that Delphi has a TNSArray.Create, in Lazarus I have found nothing similar.

Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.   AFiles: array of string;
  4.   ANSFiles: NSArray;
  5.   ANSString: NSString;
  6.   i: integer;
  7. begin
  8.  
  9.   ANSFiles := NSArray. ??? // How can I create a new array?
  10.  
  11.   for i := 0 to length(AFiles) - 1 do begin
  12.     ANSString := NSSTR(pchar(AFiles[i])));
  13.     ANSFiles. ??? // How can I add ANSString?
  14.   end;
  15.  
  16. end;          
  17.  
  18.  

Up to now, this is my code. How can I create the array and add items?

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: How to create an NSArray
« Reply #1 on: May 16, 2016, 06:51:05 pm »
look at this web
Code: Pascal  [Select][+][-]
  1. {$modeswitch objectivec1}
  2.  
  3.  
  4. var
  5.   AFiles: array of string;
  6.   ANSFiles: NSMutableArray;
  7.   ANSString: NSString;
  8.   i: integer;
  9. begin
  10.  
  11.   ANSFiles := NSMutableArray(NSMutableArray.array).init; // How can I create a new array?
  12.  
  13.   for i := 0 to length(AFiles) - 1 do begin
  14.     ANSString := NSSTR(pchar(AFiles[i])));
  15.     ANSFiles.addObject(ANSString);
  16.   end;
  17. end;
  18.  

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1059
Re: How to create an NSArray
« Reply #2 on: May 17, 2016, 08:58:28 am »
That should be "NSMutableArray.alloc" instead of "NSMutableArray.array". You also don't need the NSMutableArray() typecast, because NSMutableArray.alloc returns an id.

@LazProgger: as indirectly suggested by skalogryz, you cannot use Objective-Pascal without knowing at least some basics of Objective-C. We did not integrate Objective-C into Pascal, but created a new Pascal dialect that is almost a 1-to-1 translation of Objective-C (and that can be mixed with regular Object Pascal, like with C++ and Objective-C in Objective-C++).

See http://wiki.freepascal.org/FPC_PasCocoa for more information, but again, that assumes a basic knowledge of Objective-C. You can find a very limited overview of how to do some basic things at http://wiki.freepascal.org/FPC_PasCocoa/Differences

BeniBela

  • Hero Member
  • *****
  • Posts: 906
    • homepage
Re: How to create an NSArray
« Reply #3 on: May 17, 2016, 10:53:52 am »
An rray for the NSA?

Do not give them stuff, they will spy on you!

Especially with an r-ray, it is like an x-ray, is it not?
« Last Edit: May 17, 2016, 11:06:58 am by BeniBela »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: How to create an NSArray
« Reply #4 on: May 17, 2016, 02:32:50 pm »
An rray for the NSA?
History reference: "NS" in lots of Cocoa naming comes from NeXTSTEP system.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: How to create an NSArray
« Reply #5 on: May 17, 2016, 03:03:46 pm »
That should be "NSMutableArray.alloc" instead of "NSMutableArray.array"
Now I'm thinking that a method cannot be named "array" since array is a reserved word. So the name of the method should be array_.

packages/cocoaint/src/foundation/NSArray.inc
Code: Pascal  [Select][+][-]
  1. { NSArrayCreationCategory }
  2.   NSArrayCreationCategory = objccategory external (NSArray)
  3.     class function array_: id; message 'array';
  4.     class function arrayWithObject(anObject: id): id; message 'arrayWithObject:';
  5.    ...
  6.  

You also don't need the NSMutableArray() typecast, because NSMutableArray.alloc returns an id.
is "id" type treated as NSObject with "init" method declared?

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1059
Re: How to create an NSArray
« Reply #6 on: May 17, 2016, 03:20:46 pm »

You also don't need the NSMutableArray() typecast, because NSMutableArray.alloc returns an id.
is "id" type treated as NSObject with "init" method declared?
The "id" identifier is treated more or less the same as in Objective-C: it's an Objective-Pascal/C class instance of an arbitrary type, to which you hence can send any message that's in scope.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: How to create an NSArray
« Reply #7 on: May 17, 2016, 03:39:49 pm »
The "id" identifier is treated more or less the same as in Objective-C: it's an Objective-Pascal/C class instance of an arbitrary type, to which you hence can send any message that's in scope.
Hmm... does it mean that by
Code: [Select]
NSMutableArray.alloc|
the NSMutableArray class is still in the scope, thus calling .init method works?

(sorry, for asking the question, I'm out of OSX machine now).

LazProgger

  • Full Member
  • ***
  • Posts: 103
Re: How to create an NSArray
« Reply #8 on: May 17, 2016, 03:46:50 pm »
@Jonas: Thank you for the link. Yes, I do not know anything about Objective C. I just want to try to port an application to Mac OS X and I am trying to find some equivalents for Windows Api functions I have used in the Windows version.

So,  I have searched the web for some code and mostly found Objective C examples that are often using the NSArray type to pass information to the system. That was how I came to this question.

And thanks for the code examples! I would never had come to this on my own!
« Last Edit: May 17, 2016, 03:52:20 pm by LazProgger »

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1059
Re: How to create an NSArray
« Reply #9 on: May 17, 2016, 05:17:29 pm »
The "id" identifier is treated more or less the same as in Objective-C: it's an Objective-Pascal/C class instance of an arbitrary type, to which you hence can send any message that's in scope.
Hmm... does it mean that by
Code: [Select]
NSMutableArray.alloc|
the NSMutableArray class is still in the scope, thus calling .init method works?

The scope is the regular Pascal scope. E.g., if the unit CocoaAll is in your uses clause, then all methods from all classes, interfaces and categories declared in that unit are in scope.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: How to create an NSArray
« Reply #10 on: May 17, 2016, 05:42:57 pm »
The scope is the regular Pascal scope. E.g., if the unit CocoaAll is in your uses clause, then all methods from all classes, interfaces and categories declared in that unit are in scope.
all methods of all classes are available for "id" type?

interesting... is/were there an issue with name collisions? (resolved at compile-time by throwing an error?)

Unrealistic example:
Code: Pascal  [Select][+][-]
  1.    // ObjC method has underscore in its name
  2.   NSClass1 = objcclass
  3.     function array_ : integer; message 'array_';
  4.   end;
  5.  
  6.   // ObjC method doesn't have an underscore in its name
  7.   // but pascal declaration does
  8.   NSClass2 = objcclass
  9.     function array_ : integer; message 'array';
  10.   end;
  11.  
  12. var
  13.   m : id;
  14. ...
  15.   m.array_;
  16.  

--- Please don't bother answering. I've reread the wiki, it's explained.
« Last Edit: May 17, 2016, 05:51:57 pm by skalogryz »

LazProgger

  • Full Member
  • ***
  • Posts: 103
Re: How to create an NSArray
« Reply #11 on: May 18, 2016, 01:29:05 am »
I have tried it and the NSMutableArray.alloc.init and NSMutableArray.release thing is working.

However, neither alloc, init and relase are suggested by the code completion nor I can find something in the unit where NSArray is declared. Nevertheless, the compiler is not complaining.

Is there a reason for that?

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: How to create an NSArray
« Reply #12 on: May 18, 2016, 03:52:42 am »
Is there a reason for that?
Depends on what version of Lazarus is being used. (You've to understand that code completion is not based on FPC sources, but a stand-alone CodeTools library).

The trunk version of Lazarus finds NSArray declaration (the actual file) without problem.

But there're two other issues.
1) CodeTools seems to be confused by redeclared NSObject at (packages/cocoaint/src/AnonClassDefinitionQuartzcore.pas). That prevents Lazarus from showing "alloc" and "init" for NSArray. (Since it cannot identify that they're inherited from NSObject declared at objcbase.pas).

@Jonas, would it be reasonable to remove NSObject declaration from there?!

For Lazarus version I can easily clean this up by:
1. Removing NSObject declaration from AnonClassDefinitionQuartzcore.pas completely. 
2. in Lazarus Tools->Rescan FPC Source Directory.
After that code completion on NSArray shows all NSObject methods.

2) It might be that CodeTools are missing the feature of "id" type to have all declared objc methods available. At least it looks so. If you'd use type casting however, it would work:
Code: [Select]
NSMutableArray(NSMustableArray.alloc).|  <-- completion works
« Last Edit: May 18, 2016, 03:54:47 am by skalogryz »

 

TinyPortal © 2005-2018