5

Note: Typically in a dealloc method you should release object instance variables directly (rather than invoking a set accessor and passing nilas the parameter), as illustrated in this example:

- (void)dealloc {
    [property release];
    [super dealloc];
}

If you are using the modern runtime and synthesizing the instance variable, however, you cannot access the instance variable directly, so you must invoke the accessor method:

- (void)dealloc {
    [self setProperty:nil];
    [super dealloc];
}

What is modern runtime in iOS application development exactly?

Deepak Danduprolu
  • 44,595
  • 12
  • 101
  • 105
Pablo
  • 28,133
  • 34
  • 125
  • 215
  • Possibly related: http://stackoverflow.com/questions/5621139/is-there-any-problem-using-self-property-nil-in-dealloc – Deepak Danduprolu Jul 06 '11 at 06:59
  • There is no answer in that post to what is "modern runtime". – Pablo Jul 06 '11 at 07:03
  • 2
    That ‘you cannot access the instance variable directly’ bit used to be the case with older compilers. With modern enough compilers, you _can_ access the backing instance variable that was automatically synthesised for a declared property. –  Jul 06 '11 at 09:19

1 Answers1

10

It is possible to access the ivar directly, under the same name as the synthesized property. The @synthesize directive creates the ivar on your behalf if one does not already exist, and since that is a compiler directive, the ivar is available at compile-time. See "Runtime Difference" in the Declared Properties chapter of The Objective-C Programming Language. As Abizern noted in a comment, it's also possible to specify whatever name you like for the ivar: @synthesize coffee=tea; -- here, tea is the ivar and coffee the property.

To use the ivar, simply refer to it like any other variable, without using the dot syntax. The following is all perfectly legal and works as expected:

@interface Grisby : NSObject {}
@property (retain) NSObject * obj;
@end

@implementation Grisby

@synthesize obj;

- (void) dealloc {
    [obj release], obj = nil;
    [super dealloc];
}

- (id) init {
    self = [super init];
    if( !self ) return nil;

    obj = [NSObject new];

    return self;
}

- (NSObject *) obj {
    return [[obj retain] autorelease];
}

@end

The "modern runtime" was introduced with Mac OS X 10.5 (Leopard) as part of the transition to 64-bit. All versions of iOS use the modern runtime. Synthesized instance variables are a feature of the modern runtime, as noted in the link I provided above.

The other key difference, noted in "Runtime Versions and Platforms" of the Objective-C Runtime Programming Guide, is that instance variables are "non-fragile". There is a layer of indirection added to ivar storage and access which allows classes to add variables without affecting the storage of derived classes. It also presumably facilitates instance variable synthesis. Greg Parker has an explanation involving kittens, there's passing reference to it in Mike Ash's 2009 runtime writeup, and Bavarious here on SO has a swell post about ivar storage and class extensions.

You can see other things that changed, though without explanation, in the "Mac OS X Version 10.5 Delta" chapter of the Objective-C Runtime Reference.

Community
  • 1
  • 1
jscs
  • 63,694
  • 13
  • 151
  • 195
  • Indeed. You can even change the name of the backing iVar in `@synthesize` – Abizern Jul 06 '11 at 08:32
  • 1
    "Declared properties are a feature of the modern runtime" is not true. Synthesized ivars are a feature of the modern runtime, but you can use declared properties in both 32- and 64-bit on OS X, which implies both runtimes. – BJ Homer Jul 06 '11 at 18:32
  • @BJ Homer: Thanks for that note. I guess this is part of the confusion around the "modern runtime", properties being introduced with ObjC-2.0 and Leopard, at the same time as the MR. – jscs Jul 06 '11 at 18:41