Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

daproject85

macrumors member
Original poster
Apr 13, 2011
37
0
hey guys question:

i was doing an exercise and the book said to write the following snippet

Code:
-(id) initWithCoder:(NSCoder *) coder {
    name = [[coder decodeObjectForKey:@"EMPname"] retain];
    NSNumber *gradeBox = [coder decodeObjectForKey:@"EMPgrade"];
    grade = (int) [gradeBox integerValue];
    return self;
}

and said we need to retain the object name (defined in my class definition). my question is why do we need to retain this object? i mean ... in my main functions i have

Code:
Employee *fred = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/YOURDIRECTORY/bob.plist"];

to make this more clear here is my class interface
Code:
@interface Employee : NSObject {
@private
    NSString *name;
    int grade;
}

@property (retain) NSString *name;
@property int grade;
@end

So two questions

1. which calls initwithcoder, and name and grade are placed into the new object from my class. so why bother retaining it? i understand that decodeobject for key uses autorelease itself, so wouldn't that "autorelease" kick in after i do [fred release] in my main?

2. WHY use retain in @property (retain) NSString *name;??? i believe @property (matched with synthesize) must makes setters and getters.. so why use retain?


thanks
 
Last edited:

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
1. which calls initwithcoder, and name and grade are placed into the new object from my class. so why bother retaining it? i understand that decodeobject for key uses autorelease itself, so wouldn't that "autorelease" kick in after i do [fred release] in my main?

Objects always exist independently in Objective-C. Objects are not "placed in" other object. Only a pointer to the other object is stored. If you know UML, there is no aggregation relationships in Objective-C, only containment relationships.

So the retain is not in regards to the object itself, but the pointers to other objects, in this case name. Without the retain when name is decoded, the NSString object pointed to by name would be released (and probably dealloced) while fred still had a pointer to it. Thus fred would have a dangling pointer to a dead object.

autorelease doesn't "kick in". It happens when the closest autorelease pool is drained. Usually the closest autorelease pool is one created by NSRunLoop.

2. WHY use retain in @property (retain) NSString *name;??? i believe @property (matched with synthesize) must makes setters and getters.. so why use retain?

@synthesise does implement the getter and setter for a property. But how is it to implement it? Does it simply assign the incoming value to the instance variable (assign)? Does it release the previously set object and retain the newly set object (retain)? Does it release the previously set object and set a distinct copy of the newly set object (copy)?


Read (again) carefully the whole of the Memory Management Programming Guide. The Accessor Methods chapter goes particularly to answering your 2nd question.

The Cocoa Fundamentals Guide might also be useful.
 
Last edited:

daproject85

macrumors member
Original poster
Apr 13, 2011
37
0
So the retain is not in regards to the object itself, but the pointers to other objects, in this case name. Without the retain when name is decoded, the NSString object pointed to by name would be released (and probably dealloced) while fred still had a pointer to it. Thus fred would have a dangling pointer to a dead object.

autorelease doesn't "kick in". It happens when the closest autorelease pool is drained. Usually the closest autorelease pool is one created by NSRunLoop
.

so lets say i only have main and my [pool drain] is at the end of main function. In this case i wouldn't need to retain anything because ones my program reaches the end of main my program is done right? or do u generally have more than one NSRUNLOOP?


@synthesise does implement the getter and setter for a property. But how is it to implement it? Does it simply assign the incoming value to the instance variable (assign)? Does it release the previously set object and retain the newly set object (retain)? Does it release the previously set object and set a distinct copy of the newly set object (copy)?

i dont understand what you mean ???
here is why i have in my .h file
Code:
@property (retain) NSString *name;
and here is what i have in my .m file
Code:
@synthesize name;
so why release the previously set object and retain the newly set object? whats the point of that?
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Darealjakesh, red text, like capatalisation, is akin to shouting and is the quickest may to peeve someone off. So I'll shallow my anger and try to calmly answer your questions.


.
so lets say i only have main and my [pool drain] is at the end of main function. In this case i wouldn't need to retain anything because ones my program reaches the end of main my program is done right? or do u generally have more than one NSRUNLOOP?

Yes, if this is a command-line program and you don't run an NSRunLoop, then it is as you say, the release won't be sent until the program reaches the end of main where drain in sent to the one-and-only autorelease pool.

But this only the simplest, and least common, case. The memory management rules you're arguing against are set up for the more complex, and more common, case of GUI programs with an NSRunLoop.

You're creating a rubbish program that is only going to consume more and more memory as time goes on if you don't properly retain and release your objects. It a stupid habit to get into because you only going have to start doing the right thing once your program becomes non-trivial, or start creating non-trivial programs.

Really, if don't want to be bothered about memory-management, just turn on garbage collection.


.
i dont understand what you mean ???

Go and read the Memeory Management Guide as I suggested. It shows, at least conceptually, how the compiler creates the getter and setter methods for each of the assign, retain, and copy options.


.
so why release the previously set object and retain the newly set object? whats the point of that?

Because otherwise you'll leak memory. The previously set object won't ever get deallocated.
 

Sydde

macrumors 68030
Aug 17, 2009
2,552
7,050
IOKWARDI
Two thoughts:
-initWthCoder: is an init function, so you should probably have the "self = [super init]" bit in there (if the superclass conforms to NSCoding protocol, you might want -initWithCoder: in the call to super).

Simplify. If you are using @property, get in the habit of using dot-notation to make sure your ivars are handled properly. I think
Code:
self.name = [coder decodeObjectForKey:@"EMPname"];
is functionally equivalent to what you wrote. Why use @property if you are not going to apply it consistently?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.