Managing memory in objective-C for auto properties set as (retain) - objective-c

If I'm not using garbage collection and I have a auto property set as retain. Should I release the object in my dealloc or does the generated code handle that for me.
More clearly, will the following code leak memory if I don't release name in dealloc.
Person.h
#interface Person : NSObject {
}
#property (retain) NSString* name;
#end
Person.m
#import "Person.h"
#implementation Person
#synthesize name;
#end

The retain/assign/copy attributes of a #property only affects how they would behave in the getter and setter. You do need to manually -release the ivar in -dealloc.

yes this will create memory leak.
You should release it manually or in dealloc to prevent memory leak.
Here is another way to work with this..
//.h file
#interface Person : NSObject
{
NSString* name;
}
#end
//.m file
import "Person.h"
#implementation Person
-(void)ViewdidLoad
{
//You can use this by self.name=[Nsstring StringWithFormat:#""];
}
#end
Thanks
Shyam Parmar

Related

How to reference member variable in the implementation file

I am learning Objective-C and I am trying to split the class definition from the implementation as shown below.
Now in the code I want to reference the both of:
NSString *CarMotorCode;
NSString *CarChassisCode;
In the implementation file. I attempted to use:
self.CarMotorCode;
self.CarChassisCode;
But it does not work. Would you please let me know how to reference it.
Note: please let me know what is the right naming convention for the variables enclosed inside the brackets in the implementation section? Are they member variables?
Car2.m:
#import <Foundation/Foundation.h>
#import "Car2.h"
#implementation Car2
-(id) initWithMotorValue:(NSString *)motorCode andChassingValue:(NSInteger)ChassisCode {
self
}
#end
Car2.h
#ifndef Car2_h
#define Car2_h
#interface Car2 : NSObject {
NSString *CarMotorCode;
NSString *CarChassisCode;
}
-(id) initWithMotorValue: (NSString *) motorCode andChassingValue: (NSInteger) ChassisCode;
-(void) startCar;
-(void) stopCrar;
#end
#endif /* Car2_h */
You have declared instance variables (ivars). To get the “dot syntax”, you need to declare properties. The “dot syntax” is syntactic sugar that makes use of the “accessor methods” that are synthesized for you when you declare a property. (FWIW, it’s advised to not declare ivars manually, anyway, and rather to declare properties and let the compiler synthesize the necessary ivars. See Programming with Objective-C: Properties Control Access to an Object’s Values and Practical Memory Management: Use Accessor Methods to Make Memory Management Easier.)
Thus:
#interface Car2: NSObject
#property (nonatomic, copy) NSString *motorCode;
#property (nonatomic, copy) NSString *chassisCode;
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode;
#end
And your init method might look like:
#implementation Car2
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode {
if ((self = [super init])) {
_motorCode = [motorCode copy];
_chassisCode = [chassisCode copy];
}
return self;
}
#end
That will synthesize ivars _motorCode and _chassisCode for you behind the scenes, but you generally wouldn’t interact directly with them (except in init method, in which case you should avoid accessing properties). But in the rest of your instance methods, you could just use the properties self.motorCode and self.chassisCode.
A few unrelated notes:
I dropped the car prefix in your property names. It seems redundant to include that prefix when dealing with a car object.
I start my property names with lowercase letter as a matter of convention.
I changed the init method signature to better mirror the property names (e.g. not initWithMotorValue but rather initWithMotorCode).
Alternatively, you might use the strong memory qualifier rather than copy. E.g.
#interface Car2: NSObject
#property (nonatomic, strong) NSString *motorCode;
#property (nonatomic, strong) NSString *chassisCode;
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode;
#end
And
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode {
if ((self = [super init])) {
_motorCode = motorCode;
_chassisCode = chassisCode;
}
return self;
}
But we often use copy to protect us against someone passing a NSMutableString as one of these properties and then mutating it behind our back. But this is up to you.
You defined chassisCode to be a string in your ivar declaration, but as an NSInteger in your init method signature. Obviously, if it’s an NSInteger, change both accordingly:
#interface Car2: NSObject
#property (nonatomic, copy) NSString *motorCode;
#property (nonatomic) NSInteger chassisCode;
- (id) initWithMotorCode:(NSString *)motorCode chassisCode:(NSInteger)chassisCode;
#end
and
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSInteger)chassisCode {
if ((self = [super init])) {
_motorCode = [motorCode copy];
_chassisCode = chassisCode;
}
return self;
}
If you’re wondering why I didn’t use the property accessor methods in the init method, please see Practical Memory Management: Don’t Use Accessor Methods in Initializer Methods and dealloc.

Deallocating nonatomic copy setter

I am trying to create non-atomic copy accessors, and I read everywhere that the object should be released at the end. So, if you could help me understand whether I am doing it properly, I would appreciate it. Will the following be correct?
#interface ClassA: NSObject
{
NSString* stringA;
}
#property (nonatomic, copy) NSString* stringA;
#implementation ClassA
#synthesize stringA;
-(void) setStringA: (NSString*) stringInput {
if(stringA != stringInput) {
[stringA release];
stringA = [stringInput copy];
}
}
-(void) dealloc {
[stringA release];
[super dealloc];
}
I am looking for a confirmation whether I need to deallocate stringA in the dealloc method at the end and whether I did it correctly.
Many thanks.
You need to release it, yes. (You don't deallocate things. You release your ownership of them and they may be deallocated as a result.)
Your code is correct.
The rules are that you must release any object you receive from a method whose name begins with "alloc" or "new" or contains "copy". You also must release any object that you retain. Since you call -copy on stringInput, you are responsible for eventually releasing the object you receive from that.
#Ken Thomases is right; your code is correct. A few things, though:
You don't really need to declare the ivar, or synthesize the property, or write your own setter; all this is done for you. So your code (while correct) could be simplified to:
#interface ClassA: NSObject
#property (nonatomic, copy) NSString* stringA;
#end
#implementation ClassA
-(void) dealloc {
[_stringA release];
[super dealloc];
}
#end
Second, if you're using ARC (which I recommend), the code can be simplified even further (by removing the dealloc override completely).
#interface ClassA: NSObject
#property (nonatomic, copy) NSString* stringA;
#end
#implementation ClassA
#end
In this case stringA is released by your class on dealloc, but you don't have to write code to do that; ARC does it for you.

property as NSManagedObject in view controller for a "current NSManagedObject"

I am interested in setting a property as a subclass, say Person, of NSManagedObject in a view controller that will specify an instance of person so that I will be able to update with methods in the controller. can I do it like this?
// Viewcontroller.h
#implementation
#property (nonatomic, retain) Person* currentPerson;
#end
// ViewController.m
#implementation
#dynamic currentPerson;
-(void) doSomethingToCurrentPerson {
currentPerson.SomeAtrribute=somevalue;
}
#end
It seems like if this were not a valid way to go, it would also be possible to set a unique identifier and then store CurrentPersonUniqueID as a property and use KVC. Is there a way to get something along the lines of what I posted to work, or am I better off with something closer to the KVC approach, or something totally different?
This code won't work until you replace #dynamic by #synthesize. #dynamic tells the compiler that -setCurrentPerson: and -currentPerson are implemented somewhere else, which is not the case.
So #synthesize currentPerson will create the currentPerson's getter/setter automatically. It won't have anything to do with the fact that Person is a NSManagedObject.
Also, either you can't access to currentPerson directly with this name, you have to use its getter:
self.currentPerson.attribute = something;
// or
[self currentPerson].attribute = something;
Correct code:
// Viewcontroller.h
#implementation
#property (nonatomic, retain) Person* currentPerson;
#end
// ViewController.m
#implementation
#synthesize currentPerson;
-(void) doSomethingToCurrentPerson {
self.currentPerson.SomeAtrribute = somevalue;
}
#end

Subclass of class with synthesized readonly property cannot access instance variable in Objective-C

In the superclass MyClass:
#interface MyClass : NSObject
#property (nonatomic, strong, readonly) NSString *pString;
#end
#implementation MyClass
#synthesize pString = _pString;
#end
In the subclass MySubclass
#interface MySubclass : MyClass
#end
#implementation MySubclass
- (id)init {
if (self = [super init]) {
_pString = #"Some string";
}
return self;
}
The problem is that the compiler doesn't think that _pString is a member of MySubclass, but I have no problem accessing it in MyClass.
What am I missing?
The instance variable _pString produced by #synthesize is private to MyClass. You need to make it protected in order for MySubclass to be able to access it.
Add an ivar declaration for _pString in the #protected section of MyClass, like this:
#interface MyClass : NSObject {
#protected
NSString *_pString;
}
#property (nonatomic, strong, readonly) NSString *pString;
#end
Now synthesize the accessors as usual, and your variable will become accessible to your subclass.
I am familiar with this problem. You synthesize the variable in your .m class, so it is not imported along with the header since the _pString variable will be created as part of the implementation, and not the interface. The solution is to declare _pString in your header interface and then synthesize it anyway (it will use the existing variable instead of creating a private one).
#interface MyClass : NSObject
{
NSString *_pString; //Don't worry, it will not be public
}
#property (nonatomic, strong, readonly) NSString *pString;
#end
The given answer works perfectly fine. This is an alternative answer, that apparently Apple likes a bit more.
You can define a private extension of your class, a MyClass+Protected.h file, which needs to be included in MyClass.m and MySubclass.m.
Then, in this new file, you redefine the property as readwrite.
#interface MyClass ()
#property (strong, readwrite) NSString * pString;
#end
This alternative allows you to use the accessor self.pString rather than the ivar _pString.
Note: you still need to keep the definition of pString in your MyClass.h as is.

Automatic iVars with #synthesize

I understand that starting with iOS 4, there is now the ability to not declare iVars at all, and allow the compiler to automatically create them for you when you synthesize the property. However, I cannot find any documentation from Apple on this feature.
Also, is there any documentation on best practices or Apple recommended guidelines on using iVars and properties? I have always use properties like this:
.h file
#interface myClass {
NSIndexPath *_indexPath
}
#property(nonatomic, retain) NSIndexPath *indexPath
#end
.m file
#implementation myClass
#synthesize indexPath = _indexPath;
- (void)dealloc {
[_indexPath release];
}
#end
I use the _indexPath instead of indexPath as my iVar name to make sure that I don't ever use indexPath when I need to use self.indexPath. But now that iOS supports automatic properties, I don't need to worry about that. However, if I leave out the iVar declaration, how should I handle releasing it in my dealloc? I was taught to use iVars directly when releasing in dealloc, rather than using the property methods. If I don't have an iVar at design-time, can I just call the property method instead?
I've went through many different ways of dealing with this. My current method is to use the property access in dealloc. The reasons not to are too contrived (in my mind) to not do it, except in cases where I know the property has odd behavior.
#interface Class
#property (nonatomic, retain) id prop;
#end
#implementation Class
#synthesize prop;
- (void)dealloc;
{
self.prop = nil;
//[prop release], prop=nil; works as well, even without doing an explicit iVar
[super dealloc];
}
#end
In constrast, I do the following:
#interface SomeViewController : UIViewController
#property (nonatomic, copy) NSString *someString;
#end
and then
#implementation SomeViewController
#synthesize someString;
- (void)dealloc
{
[someString release], someString = nil;
self.someString = nil; // Needed?
[super dealloc];
}
#end
Note: At some point Apple will enable synthesize-by-default which will no longer require the #synthesize directive.
You can directly access instance variables using -> symbol instead of dot . (which will invoke ivar's corresponding accessor method):
.h
#interface myClass {
}
#property(nonatomic, retain) NSIndexPath *indexPath
#end
.m
#implementation myClass
- (void)dealloc {
[self->indexPath release];
self->indexPath = nil; // optional, if you need it
[super dealloc];
}
#end
Thus you will directly access iVar and not it's corresponding accessor method, obtaining additional benefit - performance.