Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Badges

BrianSlick · Treadmill Desk Ninja · @ @ @ @ @ @ @ @

About

Username
BrianSlick
Joined
Visits
6,622
Last Active
Roles
Tutorial Authors, Registered Users
Points
440
Posts
10,690
Website
http://www.briterideas.com
Badges
25
  • Free Utility For Lazy-Loading Getters

    Well, since I'm in an Automator service mood, here's another one. This is inspired by my other service(s), as well as Accessorizer (which I've used for a long time, although modern Xcode removes a lot of the code for which I primarily used it).

    MakeLazyLoadingGetters.zip

    EDIT: I decided to make this project a bit more formal and put it on GitHub: BTILazyLoadingGetters. It doesn't include the pre-made files, but does include a sample app that makes it easy to test changes. I've even started experimenting with unit tests, and there are a few included. Found and fixed a few bugs that are in the zip file above. So the latest and greatest is over on GitHub.

    Contents:

    - An Xcode project that builds an Automator action
    - A pre-made instance of said action
    - A sample Automator Workflow using said action

    How to make it:

    You should be able to add the files in the indicated folders below. But just in case you need to make it for yourself from scratch:

    - Build the app and then reveal the product in the Finder, just like you would for an iPhone app.
    - The .action needs to wind up in ~/Library/Automator
    - The Workflow needs to be in ~/Library/Services

    If drag-n-drop doesn't work, create a new Automator Workflow using the Service template. Name it whatever you want. Use these settings at the top:
    Service receives selected -text- in -any application-
    -checkmark OFF- Replaces selected text

    Find the new action and drag it into your workflow. It will probably be found in your "Recently Added" smart folder. Then find the "Copy to Clipboard" action and drag it after the custom action. Save. Give it a name that you like. I named mine "Copy Getters to Clipboard".

    This should appear in your Services menu any time you have text selected. If you want to assign a key command, System Preferences -> Keyboard -> Keyboard Shortcuts tab -> Select Services on the left -> Find the name you gave the Automator action, assign whatever key combo you want.

    What it does:

    Given any number of property declarations, like so:
    @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
    @property (nonatomic, strong) NSFetchedResultsController *mainFetchedResultsController;
    @property (nonatomic, strong, readonly) BTITableContentsManager *searchContentsManager;  // Might be important
    @property (nonatomic, assign, getter = isSearchResultsViaFetch) BOOL searchResultsViaFetch;
    @property (nonatomic, strong, readonly) NSMutableArray *mainContents;
    Highlight the ones for which you want getters. For sake of demonstration, I'll select them all. Select the service via Xcode menu -> Services -> WhateverYouCalledIt. Then put your cursor wherever you want these methods to go. Paste. Get this:
    - (NSManagedObjectContext *)managedObjectContext
    {
       if (_managedObjectContext == nil)
       {
          _managedObjectContext = [[NSManagedObjectContext alloc] init];
       }
       return _managedObjectContext;
    }
    
    - (NSFetchedResultsController *)mainFetchedResultsController
    {
       if (_mainFetchedResultsController == nil)
       {
          _mainFetchedResultsController = [[NSFetchedResultsController alloc] init];
       }
       return _mainFetchedResultsController;
    }
    
    - (BTITableContentsManager *)searchContentsManager
    {
       if (_searchContentsManager == nil)
       {
    #warning Instance variables for readonly properties must be explicitly defined
          _searchContentsManager = [[BTITableContentsManager alloc] init];
       }
       return _searchContentsManager;
    }
    
    - (NSMutableArray *)mainContents
    {
       if (_mainContents == nil)
       {
    #warning Instance variables for readonly properties must be explicitly defined
          _mainContents = [[NSMutableArray alloc] init];
       }
       return _mainContents;
    }
    I typically do this for arrays, dictionaries, and sets. I do it for other classes every once in a while, so figured something generic would be handy.

    Features:
    - This relies on the instance variable naming scheme that modern Xcode now employs with auto-synthesized properties. I've been doing ivInstanceVariables for a long time, and I really don't like the _instanceVariable convention, but I figure if Apple is going to standardize here I might as well play ball. If you have your own convention, simply edit the portion of the code that generates the output and rebuild your own service.
    - Note that the primitive type (BOOL) was ignored. There is a list of a dozen or so primitives that will be ignored. If I missed something common, let me know.
    - Note that the comment was ignored, too. I'm kinda clever that way.
    - Since auto-synthesized properties do NOT create instance variables for readonly properties, a helpful compiler warning has been added as a reminder to manually synthesize your property. You'll get compiler errors anyway since the instance variable won't exist, but at least with the warning you'll be reminded of what the issue is. Ask me why I included this. Go ahead, ask me.

    The Future:

    I'm mostly just throwing this out there in case anyone else would find it useful. Although I'm happy to entertain good ideas, I don't really envision changing this very much. The code is made available so you can tailor it to your liking. Feel free to point out bugs.

    Enjoy.