3

I've created a Person class, of which I instantiate two objects:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Person * __weak pweak = [Person new];
        Person *p = [Person personWithName:@"Strong" lastName:nil dateOfBirth:nil];
    }
    return 0;
}

The Person class overrides its dealloc method, so that it prints the name of the Person being deallocated.

Everything goes as expected, the weak variable doesn't keep the Person instance alive, I see this in the log ("John" is the default name of a Person object):

2013-01-23 17:36:51.333 Basics[6555:303] John is being deallocated
2013-01-23 17:36:51.335 Basics[6555:303] Strong is being deallocated

However, if I use the factory method in the assignation to the weak variable:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Person * __weak pweak = [Person personWithName:@"Weak" lastName:nil dateOfBirth:nil];
        Person *p = [Person personWithName:@"Strong" lastName:nil dateOfBirth:nil];
    }
    return 0;
}

this is what I see logged:

2013-01-23 17:44:16.260 Basics[6719:303] Strong is being deallocated
2013-01-23 17:44:16.262 Basics[6719:303] Weak is being deallocated

Am I doing something wrong?

These methods of the Person class may be concerned:

- (id)initWithName:(NSString *)name lastName:(NSString *)lastName dateOfBirth:(NSDate *)birth {
    self = [super init];
    if (self) {
        _name = name;
        _lastName = lastName;
        _dateOfBirth = birth;
    }
    return self;
}

+ (id)personWithName:(NSString *)name lastName:(NSString *)lastName dateOfBirth:(NSDate *)birth {
    return [[self alloc] initWithName:name lastName:lastName dateOfBirth:birth];
}
4

1 回答 1

1

When you allocate an object via the alloc/init method ARC gives to the creator of the object the responsability to release it later (so when you store an object as __strong it will stay alive until somebody owns it and when you store it as __weak it gets deallocated because nobody owns it).

From Apple Documentation (http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/memorymgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH)

You own any object you create You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).

When dealing with factory methods ARC treats returning variables as autoreleasing so they are released when the pool will be drained. ARC, in facts, converts your factory method to this:

+ (id)personWithName:(NSString *)name lastName:(NSString *)lastName dateOfBirth:(NSDate *)birth 
{
   return [[[self alloc] initWithName:name lastName:lastName dateOfBirth:birth] autorelease];
}
于 2013-01-23T17:05:01.190 回答