Retrieving values from a large dictionary at runtime in a MacOS app





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I come from a mostly ruby/js background. Our MacOS app hasn't been updated in a few years and there's no one on the team right now that does ObjC full time. I've always been curious, so I'm taking a crack at a ticket for a tiny feature in our MacOS app.



Here's what it boils down to:



We have a view with 5 columns, one of which displays an item's ID. We want to start displaying the facility name associated with that ID, which we currently have in a giant (~16k lines) json file.



Here's how the columns are initialized when we configure the UI:



NSTableColumn * checkedColumn = [[NSTableColumn alloc] initWithIdentifier:@"active"];
[[checkedColumn headerCell] setStringValue:@"Active"];
[checkedColumn setWidth:30];
[checkedColumn setEditable:YES];
[inventoryTable addTableColumn:checkedColumn];

NSTableColumn * idColumn = [[NSTableColumn alloc] initWithIdentifier:@"id"];
[[idColumn headerCell] setStringValue:@"ID"];
[idColumn setWidth:120];
[idColumn setEditable:NO];
[inventoryTable addTableColumn:idColumn];

NSTableColumn * ownerColumn = [[NSTableColumn alloc] initWithIdentifier:@"owner"];
[[ownerColumn headerCell] setStringValue:@"Owner"];
[ownerColumn setWidth:120];
[ownerColumn setEditable:NO];
[inventoryTable addTableColumn:ownerColumn];

NSTableColumn * countColumn = [[NSTableColumn alloc] initWithIdentifier:@"count"];
[[countColumn headerCell] setStringValue:@"Count"];
[countColumn setWidth:120];
[countColumn setEditable:NO];
[inventoryTable addTableColumn:countColumn];

NSTableColumn * pendingColumn = [[NSTableColumn alloc] initWithIdentifier:@"pending"];
[[pendingColumn headerCell] setStringValue:@"Pending"];
[pendingColumn setWidth:70];
[pendingColumn setEditable:NO];
[inventoryTable addTableColumn:pendingColumn];


I added the following to create the new column:



NSTableColumn * facilityColumn = [[NSTableColumn alloc] initWithIdentifier:@"facility"];
[[facilityColumn headerCell] setStringValue:@"Facility"];
[facilityColumn setWidth:120];
[facilityColumn setEditable:NO];
[inventoryTable addTableColumn:facilityColumn];


The original rendering in the tableView was this:



- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
IVClient * client = [allClients objectAtIndex:row];
if ([[tableColumn identifier] isEqualToString:@"id"]) {
return PropToString(client.id);
} else if ([[tableColumn identifier] isEqualToString:@"owner"]) {
return PropToString(client.owner);
} else if ([[tableColumn identifier] isEqualToString:@"count"]) {
return [NSNumber numberWithInt:client.count];
} else if ([[tableColumn identifier] isEqualToString:@"pending"]) {
return [NSNumber numberWithBool:client.pending];
} else if ([[tableColumn identifier] isEqualToString:@"active"]) {
return [NSNumber numberWithBool:client.active];
}
return nil;
}


and i added a condition to match the new value:



else if ([[tableColumn identifier] isEqualToString:@"facility"]){
return FacilityNameFromID(client.id);
}


I have only a surface level grasp of how to interact with Obj C data structures, but it seems like this should be pretty straightforward and i have to either:



1) Store the chunk of data in a dictionary and check for an ID match every time we render rows



or



2) Store it in a db and query by ID.



It seems like holding that much data in a dictionary is excessive but I'm going into this pretty blind. If I were in my comfort zone and building a backend for an api with these same specs, I'd definitely go the db route. I'm just not familiar with CoreData whatsoever.



Would #1 at least be realistic for a smaller dataset?










share|improve this question





























    0















    I come from a mostly ruby/js background. Our MacOS app hasn't been updated in a few years and there's no one on the team right now that does ObjC full time. I've always been curious, so I'm taking a crack at a ticket for a tiny feature in our MacOS app.



    Here's what it boils down to:



    We have a view with 5 columns, one of which displays an item's ID. We want to start displaying the facility name associated with that ID, which we currently have in a giant (~16k lines) json file.



    Here's how the columns are initialized when we configure the UI:



    NSTableColumn * checkedColumn = [[NSTableColumn alloc] initWithIdentifier:@"active"];
    [[checkedColumn headerCell] setStringValue:@"Active"];
    [checkedColumn setWidth:30];
    [checkedColumn setEditable:YES];
    [inventoryTable addTableColumn:checkedColumn];

    NSTableColumn * idColumn = [[NSTableColumn alloc] initWithIdentifier:@"id"];
    [[idColumn headerCell] setStringValue:@"ID"];
    [idColumn setWidth:120];
    [idColumn setEditable:NO];
    [inventoryTable addTableColumn:idColumn];

    NSTableColumn * ownerColumn = [[NSTableColumn alloc] initWithIdentifier:@"owner"];
    [[ownerColumn headerCell] setStringValue:@"Owner"];
    [ownerColumn setWidth:120];
    [ownerColumn setEditable:NO];
    [inventoryTable addTableColumn:ownerColumn];

    NSTableColumn * countColumn = [[NSTableColumn alloc] initWithIdentifier:@"count"];
    [[countColumn headerCell] setStringValue:@"Count"];
    [countColumn setWidth:120];
    [countColumn setEditable:NO];
    [inventoryTable addTableColumn:countColumn];

    NSTableColumn * pendingColumn = [[NSTableColumn alloc] initWithIdentifier:@"pending"];
    [[pendingColumn headerCell] setStringValue:@"Pending"];
    [pendingColumn setWidth:70];
    [pendingColumn setEditable:NO];
    [inventoryTable addTableColumn:pendingColumn];


    I added the following to create the new column:



    NSTableColumn * facilityColumn = [[NSTableColumn alloc] initWithIdentifier:@"facility"];
    [[facilityColumn headerCell] setStringValue:@"Facility"];
    [facilityColumn setWidth:120];
    [facilityColumn setEditable:NO];
    [inventoryTable addTableColumn:facilityColumn];


    The original rendering in the tableView was this:



    - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    IVClient * client = [allClients objectAtIndex:row];
    if ([[tableColumn identifier] isEqualToString:@"id"]) {
    return PropToString(client.id);
    } else if ([[tableColumn identifier] isEqualToString:@"owner"]) {
    return PropToString(client.owner);
    } else if ([[tableColumn identifier] isEqualToString:@"count"]) {
    return [NSNumber numberWithInt:client.count];
    } else if ([[tableColumn identifier] isEqualToString:@"pending"]) {
    return [NSNumber numberWithBool:client.pending];
    } else if ([[tableColumn identifier] isEqualToString:@"active"]) {
    return [NSNumber numberWithBool:client.active];
    }
    return nil;
    }


    and i added a condition to match the new value:



    else if ([[tableColumn identifier] isEqualToString:@"facility"]){
    return FacilityNameFromID(client.id);
    }


    I have only a surface level grasp of how to interact with Obj C data structures, but it seems like this should be pretty straightforward and i have to either:



    1) Store the chunk of data in a dictionary and check for an ID match every time we render rows



    or



    2) Store it in a db and query by ID.



    It seems like holding that much data in a dictionary is excessive but I'm going into this pretty blind. If I were in my comfort zone and building a backend for an api with these same specs, I'd definitely go the db route. I'm just not familiar with CoreData whatsoever.



    Would #1 at least be realistic for a smaller dataset?










    share|improve this question

























      0












      0








      0








      I come from a mostly ruby/js background. Our MacOS app hasn't been updated in a few years and there's no one on the team right now that does ObjC full time. I've always been curious, so I'm taking a crack at a ticket for a tiny feature in our MacOS app.



      Here's what it boils down to:



      We have a view with 5 columns, one of which displays an item's ID. We want to start displaying the facility name associated with that ID, which we currently have in a giant (~16k lines) json file.



      Here's how the columns are initialized when we configure the UI:



      NSTableColumn * checkedColumn = [[NSTableColumn alloc] initWithIdentifier:@"active"];
      [[checkedColumn headerCell] setStringValue:@"Active"];
      [checkedColumn setWidth:30];
      [checkedColumn setEditable:YES];
      [inventoryTable addTableColumn:checkedColumn];

      NSTableColumn * idColumn = [[NSTableColumn alloc] initWithIdentifier:@"id"];
      [[idColumn headerCell] setStringValue:@"ID"];
      [idColumn setWidth:120];
      [idColumn setEditable:NO];
      [inventoryTable addTableColumn:idColumn];

      NSTableColumn * ownerColumn = [[NSTableColumn alloc] initWithIdentifier:@"owner"];
      [[ownerColumn headerCell] setStringValue:@"Owner"];
      [ownerColumn setWidth:120];
      [ownerColumn setEditable:NO];
      [inventoryTable addTableColumn:ownerColumn];

      NSTableColumn * countColumn = [[NSTableColumn alloc] initWithIdentifier:@"count"];
      [[countColumn headerCell] setStringValue:@"Count"];
      [countColumn setWidth:120];
      [countColumn setEditable:NO];
      [inventoryTable addTableColumn:countColumn];

      NSTableColumn * pendingColumn = [[NSTableColumn alloc] initWithIdentifier:@"pending"];
      [[pendingColumn headerCell] setStringValue:@"Pending"];
      [pendingColumn setWidth:70];
      [pendingColumn setEditable:NO];
      [inventoryTable addTableColumn:pendingColumn];


      I added the following to create the new column:



      NSTableColumn * facilityColumn = [[NSTableColumn alloc] initWithIdentifier:@"facility"];
      [[facilityColumn headerCell] setStringValue:@"Facility"];
      [facilityColumn setWidth:120];
      [facilityColumn setEditable:NO];
      [inventoryTable addTableColumn:facilityColumn];


      The original rendering in the tableView was this:



      - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
      IVClient * client = [allClients objectAtIndex:row];
      if ([[tableColumn identifier] isEqualToString:@"id"]) {
      return PropToString(client.id);
      } else if ([[tableColumn identifier] isEqualToString:@"owner"]) {
      return PropToString(client.owner);
      } else if ([[tableColumn identifier] isEqualToString:@"count"]) {
      return [NSNumber numberWithInt:client.count];
      } else if ([[tableColumn identifier] isEqualToString:@"pending"]) {
      return [NSNumber numberWithBool:client.pending];
      } else if ([[tableColumn identifier] isEqualToString:@"active"]) {
      return [NSNumber numberWithBool:client.active];
      }
      return nil;
      }


      and i added a condition to match the new value:



      else if ([[tableColumn identifier] isEqualToString:@"facility"]){
      return FacilityNameFromID(client.id);
      }


      I have only a surface level grasp of how to interact with Obj C data structures, but it seems like this should be pretty straightforward and i have to either:



      1) Store the chunk of data in a dictionary and check for an ID match every time we render rows



      or



      2) Store it in a db and query by ID.



      It seems like holding that much data in a dictionary is excessive but I'm going into this pretty blind. If I were in my comfort zone and building a backend for an api with these same specs, I'd definitely go the db route. I'm just not familiar with CoreData whatsoever.



      Would #1 at least be realistic for a smaller dataset?










      share|improve this question














      I come from a mostly ruby/js background. Our MacOS app hasn't been updated in a few years and there's no one on the team right now that does ObjC full time. I've always been curious, so I'm taking a crack at a ticket for a tiny feature in our MacOS app.



      Here's what it boils down to:



      We have a view with 5 columns, one of which displays an item's ID. We want to start displaying the facility name associated with that ID, which we currently have in a giant (~16k lines) json file.



      Here's how the columns are initialized when we configure the UI:



      NSTableColumn * checkedColumn = [[NSTableColumn alloc] initWithIdentifier:@"active"];
      [[checkedColumn headerCell] setStringValue:@"Active"];
      [checkedColumn setWidth:30];
      [checkedColumn setEditable:YES];
      [inventoryTable addTableColumn:checkedColumn];

      NSTableColumn * idColumn = [[NSTableColumn alloc] initWithIdentifier:@"id"];
      [[idColumn headerCell] setStringValue:@"ID"];
      [idColumn setWidth:120];
      [idColumn setEditable:NO];
      [inventoryTable addTableColumn:idColumn];

      NSTableColumn * ownerColumn = [[NSTableColumn alloc] initWithIdentifier:@"owner"];
      [[ownerColumn headerCell] setStringValue:@"Owner"];
      [ownerColumn setWidth:120];
      [ownerColumn setEditable:NO];
      [inventoryTable addTableColumn:ownerColumn];

      NSTableColumn * countColumn = [[NSTableColumn alloc] initWithIdentifier:@"count"];
      [[countColumn headerCell] setStringValue:@"Count"];
      [countColumn setWidth:120];
      [countColumn setEditable:NO];
      [inventoryTable addTableColumn:countColumn];

      NSTableColumn * pendingColumn = [[NSTableColumn alloc] initWithIdentifier:@"pending"];
      [[pendingColumn headerCell] setStringValue:@"Pending"];
      [pendingColumn setWidth:70];
      [pendingColumn setEditable:NO];
      [inventoryTable addTableColumn:pendingColumn];


      I added the following to create the new column:



      NSTableColumn * facilityColumn = [[NSTableColumn alloc] initWithIdentifier:@"facility"];
      [[facilityColumn headerCell] setStringValue:@"Facility"];
      [facilityColumn setWidth:120];
      [facilityColumn setEditable:NO];
      [inventoryTable addTableColumn:facilityColumn];


      The original rendering in the tableView was this:



      - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
      IVClient * client = [allClients objectAtIndex:row];
      if ([[tableColumn identifier] isEqualToString:@"id"]) {
      return PropToString(client.id);
      } else if ([[tableColumn identifier] isEqualToString:@"owner"]) {
      return PropToString(client.owner);
      } else if ([[tableColumn identifier] isEqualToString:@"count"]) {
      return [NSNumber numberWithInt:client.count];
      } else if ([[tableColumn identifier] isEqualToString:@"pending"]) {
      return [NSNumber numberWithBool:client.pending];
      } else if ([[tableColumn identifier] isEqualToString:@"active"]) {
      return [NSNumber numberWithBool:client.active];
      }
      return nil;
      }


      and i added a condition to match the new value:



      else if ([[tableColumn identifier] isEqualToString:@"facility"]){
      return FacilityNameFromID(client.id);
      }


      I have only a surface level grasp of how to interact with Obj C data structures, but it seems like this should be pretty straightforward and i have to either:



      1) Store the chunk of data in a dictionary and check for an ID match every time we render rows



      or



      2) Store it in a db and query by ID.



      It seems like holding that much data in a dictionary is excessive but I'm going into this pretty blind. If I were in my comfort zone and building a backend for an api with these same specs, I'd definitely go the db route. I'm just not familiar with CoreData whatsoever.



      Would #1 at least be realistic for a smaller dataset?







      objective-c macos cocoa






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 23:43









      alexalex

      685




      685
























          1 Answer
          1






          active

          oldest

          votes


















          1














          16K lines, or even records, does not qualify as "giant" or even particularly large, in my eyes. A dictionary should be adequate. Certainly, it's where you should start before measuring and determining if the performance is a real problem. (Premature optimization and all that.)



          After that, the first optimization I'd try would be to make a read-only property of IVClient called facilityName whose getter implementation does the lookup with caching. That is, something like:



          - (NSString*) facilityName
          {
          if (!_facilityName)
          _facilityName = FacilityNameFromID(self.id);
          return _facilityName;
          }





          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453951%2fretrieving-values-from-a-large-dictionary-at-runtime-in-a-macos-app%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            16K lines, or even records, does not qualify as "giant" or even particularly large, in my eyes. A dictionary should be adequate. Certainly, it's where you should start before measuring and determining if the performance is a real problem. (Premature optimization and all that.)



            After that, the first optimization I'd try would be to make a read-only property of IVClient called facilityName whose getter implementation does the lookup with caching. That is, something like:



            - (NSString*) facilityName
            {
            if (!_facilityName)
            _facilityName = FacilityNameFromID(self.id);
            return _facilityName;
            }





            share|improve this answer




























              1














              16K lines, or even records, does not qualify as "giant" or even particularly large, in my eyes. A dictionary should be adequate. Certainly, it's where you should start before measuring and determining if the performance is a real problem. (Premature optimization and all that.)



              After that, the first optimization I'd try would be to make a read-only property of IVClient called facilityName whose getter implementation does the lookup with caching. That is, something like:



              - (NSString*) facilityName
              {
              if (!_facilityName)
              _facilityName = FacilityNameFromID(self.id);
              return _facilityName;
              }





              share|improve this answer


























                1












                1








                1







                16K lines, or even records, does not qualify as "giant" or even particularly large, in my eyes. A dictionary should be adequate. Certainly, it's where you should start before measuring and determining if the performance is a real problem. (Premature optimization and all that.)



                After that, the first optimization I'd try would be to make a read-only property of IVClient called facilityName whose getter implementation does the lookup with caching. That is, something like:



                - (NSString*) facilityName
                {
                if (!_facilityName)
                _facilityName = FacilityNameFromID(self.id);
                return _facilityName;
                }





                share|improve this answer













                16K lines, or even records, does not qualify as "giant" or even particularly large, in my eyes. A dictionary should be adequate. Certainly, it's where you should start before measuring and determining if the performance is a real problem. (Premature optimization and all that.)



                After that, the first optimization I'd try would be to make a read-only property of IVClient called facilityName whose getter implementation does the lookup with caching. That is, something like:



                - (NSString*) facilityName
                {
                if (!_facilityName)
                _facilityName = FacilityNameFromID(self.id);
                return _facilityName;
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 24 '18 at 0:10









                Ken ThomasesKen Thomases

                71.9k673110




                71.9k673110
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453951%2fretrieving-values-from-a-large-dictionary-at-runtime-in-a-macos-app%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()