Reputation: 3622
I did some iOS
development back when iOS 3.0 came out, but for two years I lost track of how iOS was doing.
I remember that you would do retain back in iOS
3.0 and even so, I still don't remember exactly what the reason for retaining in a setter was. This is just the one thing that is stumping me so far.
And last but not least there's the idea that local variables are strong by default in iOS 5 with ARC. How can they be strong if some of them don't have setters? (As an example, id.)
Some code to explain what I mean:
+(double) popOperandOffStack:(NSMutableArray *) stack{
double result = 0;
id topOfStack = [stack lastObject];
// how is topOfStack retaining [stack lastObject] if it's simply id?
if (topOfStack) [stack removeLastObject];
if ([topOfStack isKindOfClass:[NSNumber class]]){
result = [topOfStack doubleValue];
}
else if ([topOfStack isKindOfClass:[NSString class]]){
if ([topOfStack isEqualToString:@"+"]){
result = [self popOperandOffStack:stack] + [self popOperandOffStack:stack];
}
if ([topOfStack isEqualToString:@"-"]){
result = [self popOperandOffStack:stack] - [self popOperandOffStack:stack];
}
if ([topOfStack isEqualToString:@"*"]){
result = [self popOperandOffStack:stack] * [self popOperandOffStack:stack];
}
if ([topOfStack isEqualToString:@"/"]){
result = [self popOperandOffStack:stack] / [self popOperandOffStack:stack];
}
}
return result;
}
Upvotes: 0
Views: 1383
Reputation: 33592
You appear to be confusing properties with instance variables and local variables.
Variables do not have setters. Properties have setters. Properties of any type can have setters (except possibly void). Instance variables might happen to correspond to properties, but the variables themselves do not have "setters". obj->ivar
will never call a setter, not even under ARC.
ARC simply does approximately three things:
Insert retain
, release
, autorelease
, and dealloc
for you. When you write
// ARC
{
id foo = [array lastObject];
...
}
it gets translated to approximately
// MRC
{
id foo = [[array lastObject] retain];
...
[foo release];
}
It uses Objective-C naming conventions to figure out what it needs to retain and release. There are a few optimizations (it actually uses objc_retain()
and friends for reasons described in the ARC spec, plus a few more functions to handle autoreleased objects more efficiently than -autorelease
.)
Release __strong
ivars in -dealloc
for you. It does not call the property setters; it just releases the ivars. It might also set them to nil
.
Zeroing weak references.__weak
variables are read/written with objc_copyWeak()
and friends instead of being accessed directly. There's additionally a hook in -[NSObject release]
(or so) in order to implement zeroing weak references correctly.
Additionally, the semantics surrounding blocks and __block
variables are changed in a way that isn't easy to replicate via MRC. Apart from that, I believe everything ARC does can be replicated by calling the ARC runtime support function calls.
The only connection between ARC and setters is that you can get rid of a lot of properties, because the compiler inserts retain/release on ivar access.
Upvotes: 1
Reputation: 726479
You can send messages to objects without knowing their exact type at compile time. In fact, you routinely do that when you send messages to objects that you get back from arrays: you do not need to cast id
to the exact type, you can simply send a message, and Objective C will dispatch it correctly. The only exception to this rule is accessing properties with the dot .
syntax: you do need a cast there.
Every object whose class inherits from NSObject
responds to retain
, release
, autorelease
, and so on. This is all that the ARC needs to know. In the worst case you will get "an object does not respond to selector" message if an id
that you have happens to point to something invalid.
Upvotes: 2