views:

370

answers:

5

When adding new properties to classes, I find myself typing the same things over and over in xcode:

  1. add TYPE *NAME; (in .h interface)
  2. add @property (nonatomic, retain) TYPE *NAME; (in .h)
  3. add @synthesize NAME; (in .m)
  4. add [NAME release]; (in .m dealloc)

(I'm in a non-garbage collected environment.)

How can I do this automatically?

+1  A: 

That sounds about right. IIRC, the Objective-C 2.0 doc says you might be able to leave out step #1, but otherwise I don't know of any shortcuts.

You could probably write a user script to do so within Xcode. See http://www.mactech.com/articles/mactech/Vol.23/23.01/2301XCode/index.html.

Robert Sanders
A: 

According to the Developer Documentation in 64bit runtimes you can leave out step 1.

Georg
A: 

You could look at Andrew Pang's RMModelObject - I haven't used it, but it acts as a object base class that simplifies model creation.

I haven't used it, but here's some of what's highlighted in the readme:

  • no need to declare instance variables,
  • no need to write accessor methods,
  • free NSCopying protocol support (-copyWithZone:),
  • free NSCoding protocol support (-initWithCoder:, -encodeWithCoder:),
  • free -isEqual: and -hash` implementation,
  • no need to write -dealloc in most cases.
Jablair
A: 

Here's another solution which I modified from this article (also see the initial article)

The version in the blog was searching for variables outside of the variable declaration block and was matching method names too. I have done a crude fix to only search for variables before the first '}'. This will break if there are multiple interface declarations in the header file.

I set the output to "Replace Document Conents" and input as "Entire Document" ....

#!/usr/bin/python

thisfile = '''%%%{PBXFilePath}%%%'''
code = '''%%%{PBXAllText}%%%'''
selmark = '''%%%{PBXSelection}%%%'''

import re

if thisfile.endswith('.h'):
    variableEnd = code.find('\n', code.find('}'))
    properties = []
    memre = re.compile('\s+(?:IBOutlet)?\s+([^\-+@].*? \*?.*?;)')
    for match in memre.finditer(code[:variableEnd]):
        member = match.group(1)
        retain = member.find('*') != -1 and ', retain' or ''
        property = '@property (nonatomic%s) %s' % (retain,member)
        if code.find(property) == -1:
            properties.append(property)
    if properties:
        print '%s\n\n%s%s%s%s' % (code[:variableEnd],selmark,'\n'.join(properties),selmark,code[variableEnd:])
elif thisfile.endswith('.m'):
    headerfile = thisfile.replace('.m','.h')
    properties = []
    retains = []
    propre = re.compile('@property\s\((.*?)\)\s.*?\s\*?(.*?);')
    header = open(headerfile).read()
    for match in propre.finditer(header):
        if match.group(1).find('retain') != -1:
            retains.append(match.group(2))
        property = '@synthesize %s;' % match.group(2)
        if code.find(property) == -1:
            properties.append(property)
    pindex = code.find('\n', code.find('@implementation'))
    if properties and pindex != -1:
        output = '%s\n\n%s%s%s' % (code[:pindex],selmark,'\n'.join(properties),selmark)
        if retains:
            dindex = code.find('\n', code.find('(void)dealloc'))
            output += code[pindex:dindex]
            retainsstr = '\n\t'.join(['[%s release];' % retain for retain in retains])
            output += '\n\t%s' % retainsstr
            pindex = dindex
        output += code[pindex:]
        print output
Cal
A: 

There is Kevin Callahan's Accessorizer. From the web page:

Accessorizer selects the appropriate property specifiers based on ivar type - and can also generate explicit accessors (1.0) automagically ... but Accessorizer does much, much more ...

Peter N Lewis