IS this class Many part of memory Leak - iphone

I am much confuse about my class.
Specially about Memory Management.
Please Guide me about NSString Concept at here.
My Class is.
#import <Foundation/Foundation.h>
#interface itinerary_detail : NSObject {
NSString *itinerary_title;
NSString *itinerary_creator;
NSString *itinerary_identifiere;
NSString *itinerary_created;
NSString *itinerary_modified;
}
#property (retain) NSString *itinerary_title;
#property (retain) NSString *itinerary_creator;
#property (retain) NSString *itinerary_identifiere;
#property (retain) NSString *itinerary_created;
#property (retain) NSString *itinerary_modified;
-(void) itinerary_initialization;
-(void) itinerary_title:(NSString *) xml_value;
-(void) itinerary_creator:(NSString *) xml_value;
-(void) itinerary_identifiere:(NSString *) xml_value;
-(void) itinerary_created:(NSString *) xml_value;
-(void) itinerary_modified:(NSString *) xml_value;
#end
and My .m class is
#import "itinerary_detail.h"
#implementation itinerary_detail
#synthesize itinerary_title,itinerary_creator,itinerary_identifiere,itinerary_created,itinerary_modified;
-(void) itinerary_initialization
{
itinerary_title=#"null";
itinerary_creator=#"null";
itinerary_identifiere=#"null";
itinerary_created=#"null";
itinerary_modified=#"null";
}
-(void) itinerary_title:(NSString *) xml_value
{
itinerary_title=xml_value;
}
-(void) itinerary_creator:(NSString *) xml_value
{
itinerary_creator=xml_value;
}
-(void) itinerary_identifiere:(NSString *) xml_value
{
itinerary_identifiere=xml_value;
}
-(void) itinerary_created:(NSString *) xml_value
{
itinerary_created=xml_value;
}
-(void) itinerary_modified:(NSString *) xml_value
{
itinerary_modified=xml_value;
}
-(void) dealloc
{
[itinerary_title release];
[itinerary_creator release];
[itinerary_identifiere release];
[itinerary_created release];
[itinerary_modified release];
[super dealloc];
}
#end
My question about.
1- Is this type Deceleration of NSString in this class of Memory Leak Issue. If Yes Please How i Will change this.
2- I am Using This class into Other class
Like that
itinerary_detail *check=[[itinerary_detail alloc] init];
[check itinerary_initialization];
[check release];
my question is this right way . or this is also a Memory Leak Issue.
Please Guide Me How to Deceleration Of this class and How to handle all memory Leak Issues.
Please Help Me

The problem come from the fact that you don't use the property but directly access the member variable. replace itinerary_title=xml_valueby self.itinerary_title=xml_value
btw, string properties are usually (copy) and not (retain) and why do you create all those methods while the synthesize will do it for you.
remove the methods from the .h file and from the .m file and set the property as
#property (copy) NSString* myString;

Your code shows that you need to get the basics of Cocoa and Objective-C right, before writing an actual program. Read Cocoa Fundamentals, OOP with Objective-C, etc. Resist the urge to start writing programs right now; the time you'll spend to learn the basics will greatly reduce your headache later.
Your code should look like:
#interface ItineraryDetail : NSObject {
NSString *itineraryTitle;
...
}
#property (retain) NSString *itineraryTitle;
#end
and
#implementation ItineraryDetail
#synthesize itineraryTitle, ... ;
-(id)init{
self=[super init];
if(self){
itineraryTitle=nil;
}
return self;
}
-(void) dealloc
{
[itineraryTitle release];
[super dealloc];
}
#end
and
ItineraryDetail *check=[[ItineraryDetail alloc] init];
... use it ...
[check release];
A few points:
In Objective-C, you don't usually name_like_this. You NameLikeThis. This is not an absolute rule, but it's customary, and you should follow it in general.
You don't write a method like ...Initialize separately. Rather, it's implemented using init, with [super init] inside it.
When you synthesize a property named foo via #synthesize foo, the setter setFoo: and the getter foo: are automatically generated, so you don't have to provide them manually. And you mistakenly used the name foo: for the setter! That will totally confuse the system.
The nil value for NSString (or any object in Objective-C in general) is not #"null" but just nil. And the ivars are set to nil automatically by the system, so you don't really do that in the initialization method.

Related

How can I create a wrapper to use blocks for a class that uses callbacks?

I'm diving into iOS programming and I'm learning how to use blocks. I have a sucky, over-engineered library that I'm using in my project and it uses a single callback method to handle all data requests...
#protocol SuckyClassDelegate <NSObject>
-(void)returnedSuckyData:(NSMutableDictionary*)data;
#end
#interface SuckyClass: NSObject
#property (nonatomic, weak) id<SuckyClassDelegate> delegate;
-(void)getSuckyData;
#end
#interface MyViewController: UIViewController <SuckyClassDelegate>
-(void)requestDataFromSuckyClass;
#end
I'd like to create a wrapper class for the SuckyClass that allows me to use blocks when I need to access data from the SuckyClass, but I don't know how to do this. I'd like to have something like this...
#interface SuckyClassWrapper
- (void)requestDataWithSuccessBlock:(void(^)((NSMutableDictionary*)data))successBlock;
#end
#implementation MyViewController
-(void)requestDataFromSuckyClass {
SuckyClassWrapper *wrapper = [[SuckyClassWrapper alloc] init];
[wrapper requestDataWithSuccessBlock:^(NSMutableDictionary *data) {
NSLog(#"%#", data);
}
}
#end
...but I can't figure out how to convert the callback process into blocks. Can anyhow give me some direction here?
Thanks in advance for your wisdom!
By the way, I just whipped up the code without testing it, so I apologize if there are any typos.
The trick is to copy the completion block to a class iVar that you can then call later.
#property (nonatomic, copy) void (^errorHandler)(NSError *);
#property (nonatomic, copy) void (^successHandler)(NSString *);
Here is a method that saves two blocks for use later and then calls another class method:
- (void)methodWithErrorHandler:(void(^)(NSError *error))errorBlock successHandler: (void(^)(NSString *data))successBlock
{
// Copy the blocks to use later
self.successHandler = successBlock;
self.errorHandler = errorBlock;
// Run code
[self doOtherThings];
}
Later - when what we want to do has completed, we have another method that we call to run the blocks. In this silly example code we check to see if a class property self.error is nil. If it is not nil, we send that error to our saved error block. If it is nil, we pass self.data to the success block.
- (void)finishThingsUp
{
// Check to see if we should call the error block or the success block
if (self.error) {
self.errorHandler(self.error);
} else {
self.successHandler(self.data);
}
// Clean up the blocks
self.errorHandler = nil;
self.successHandler = nil;
}
We could use like this:
typedef void (^SuccessDataBlock)(NSMutableDictionary *);
#interface SuckyClassWrapper : NSObject <SuckyClassDelegate>
#property (nonatomic, retain) NSData *inputData;
#property (nonatomic, copy) SuccessDataBlock completionHandler;
+ (id)requestData:(NSData *)data successBlock:(SuccessDataBlock)handler;
#end
#implementation SuckyClassWrapper
#synthesize inputData;
#synthesize completionHandler;
- (id)initWithData:(NSData *)data completionHandler:(SuccessDataBlock)handler
{
self = [super init];
if (self != nil)
{
inputData = [data retain];
self.completionHandler = handler;
}
return self;
}
+ (id)requestData:(NSData *)data successBlock:(SuccessDataBlock)handler
{
return [[[self alloc] initWithData:data completionHandler:handler] autorelease];
}
//implement SuckyClass delegate
- (void)returnedSuckyData:(NSMutableDictionary *)data
{
self.completionHandler(data);
}
#end
Usage:
SuckyClassWrapper *wrapper = [SuckyClassWrapper requestData:data successBlock:^(NSMutableDictionary *successData) {
//your code here
}];

Is only one release is needed in my Objective C code?

For some reason I can't use arc, so in my code below..
Foo.h
#interface Foo : NSObject
#property (nonatomic, copy) NSString * string;
#end
Foo.m
#implementation Foo
#synthesize string=_string;
- (void) bar {
self.string = [NSString stringWithFormat:#"test1"];
self.string = [NSString stringWithFormat:#"test2"];
}
-(void) dealloc
{
[_string release];
[super dealloc];
}
#end
The bar method might not always be called, or they can be called multitime.
Is only one release in the dealloc is all needed?
Yes, since you are using properties so setter method will take care of releasing memory allocation.It will allocate memory as follows:
-(void)setValue:(NSString *)strValue
{
if(string)
{
[string release];
string = nil;
}
string = [strValue copy];
}
Is only one release in the dealloc is all needed?
Yes.
Explanation: the setter method releases the old object that was assigned to the property and retains the new one.

Program received signal:EXC_BAD_ACCESS. What to do with this?

I just recently started learning Objective C/Cocoa and I know how important the memory management is and I believe this error I've been having is regarding to that.
I have a very very simple screen: two UITextView, one Button, one UILabel.
My header file has:
#interface PontaiViewController : UIViewController {
UITextField *loginField;
UITextField *passwordField;
UILabel *userID;
}
#property (nonatomic, retain) IBOutlet UITextField *loginField;
#property (nonatomic, retain) IBOutlet UITextField *passwordField;
#property (nonatomic, retain) IBOutlet UILabel *userID;
- (IBAction) btnLoginClicked:(id) sender;
The implementation has:
#implementation PontaiViewController
#synthesize loginField;
#synthesize passwordField;
#synthesize userID;
-(IBAction) btnLoginClicked:(id)sender {
NSString *string1 = #"username=";
NSString *string2 = [string1 stringByAppendingString:(loginField.text)];
NSString *string3 = [string2 stringByAppendingString:(#"&password=")];
NSString *post = [string3 stringByAppendingString:(passwordField.text)];
NSLog(#"The post is %#", post);
userID.text=loginField.text;
[string1 release];
[string2 release];
[string3 release];
[post release];
}
and it finishes with
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.loginField=nil;
self.passwordField=nil;
self.userID=nil;
}
- (void) dealloc {
[super dealloc];
[loginField release];
[passwordField release];
[userID release];
}
When I run this demo, and try to write something in the TextView, I get this error.
What could it be?
Regards,
Felipe
Also, your NSStrings are autoreleased, and then you're releasing them again (over releasing). Read up on memory management of convenience methods.
stringByAppendingString returns an autoreleased object, don't release string1, string2, string3 and post.
In viewDidUnload you set loginField to nil, then you try to release it in dealloc. This isn't right. You only need to release valid items that you own.
Additionally, (as pointed out in a comment) you need to put [super dealloc] at the end of the dealloc function.
As pointed out by others, you also should not release the strings you're getting from stringByAppendingString.
Here are some basic rules about how to manage memory in Objective-C under iOS:
https://developer.apple.com/library/ios/#documentation/general/conceptual/devpedia-cocoacore/MemoryManagement.html
One thing you will find is that you only release stuff you are responsible for, and you're not responsible for it unless it was created with one of these:
alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone
You should comment out the following
//[string1 release];
//[string2 release];
//[string3 release];
//[post release];
since you are using helper methods and not explicitly allocating anything.

Correct way to create/use a Singleton NSMutableArray for Xcode 4

I've reviewed (and tried) a bunch of the threads here regarding Singletons and NSMutableArrays. I'm new to Objective-C so please bear with me.
I simply want to create a few arrays that can be accessed from any view/.m file.
What is the best (or most concise) coding for a Singleton?
Below is what I have now and I get
1 warning at .m '#implementation' - "Incomplete implementation"
1 error at usage in a view .m file - "initializer element is not a compile-time constant"
This is the code I have now - my GlobalData.h file:
#import <Foundation/Foundation.h>
#interface GlobalData : NSObject {
NSMutableArray *listOfHeadings;
NSMutableArray *listOfItems1;
NSMutableArray *listOfItems2;
}
#property(nonatomic,retain)NSMutableArray *listOfHeadings;
#property(nonatomic,retain)NSMutableArray *listOfItems1;
#property(nonatomic,retain)NSMutableArray *listOfItems2;
+(GlobalData*)getInstance;
#end
My GlobalData.m file:
#import "GlobalData.h"
#implementation GlobalData
#synthesize listOfHeadings;
#synthesize listOfItems1;
#synthesize listOfItems2;
static GlobalData *instance=nil;
+(GlobalData *)getInstance
{
#synchronized(self)
{
if(instance==nil)
{
instance= [GlobalData new];
}
}
return instance;
}
#end
And in a view .m file (simplified):
#import GlobalData.h
GlobalData *globDat=[GlobalData getInstance]; //error occurs here
Can someone point out the trouble and if there's better coding, please enlighten me - thanks!
EDIT
Here's a few links I've tried to use:
Can i have a single NSMutableArray in my multiple views application?
iPhone help with singleton class
In this case, you might be doing more than you have to. Granted this certainly isn't always the best solution - but you can put your NSMutableArray as a property in your App Delegate and then easily refer to it from any view. By doing it this way - you aren't locking it in as a 'singleton' but there is a 'singleton instance' of it (this helps a great deal for testability).
I have simplified this process here:
YourAppDelegate.h
#property (nonatomic,retain) NSMutableArray *myArray;
YourAppDelegate.m
#synthesize myArray;
YourViewController.m
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *myArrayFromAppDelegate = appDelegate.myArray;
From this point - you can do any manipulation on this value.
Here's the "modern" version of a single method to turn any class into a Singleton (in this case formatted as a code snippet). It works in iOS4.x or higher:
+(<#SingletonClassName#> *) sharedInstance
{
static <#SingletonClassName#> *_sharedClient = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedClient = [[self alloc] init];
});
return _sharedClient;
}
But, do you really need a singleton of a single NSMutableArray? You could use the built-on singleton - your application delegate, which is got to by calling:
MyAppDelegate * appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.myMutableArray addObject:...];
The error initializer element is not a compile-time constant is not related to how you create your singleton. The error is how you are accessing your singleton. You are doing this outside of a function:
GlobalData *globDat=[GlobalData getInstance];
This means that you are trying to initialize a global variable (globDat) as the value of the expression [GlobalData getInstance]. You can only initialize global variables to expressions that are "compile-time constants". That means things like 0 or "fred" or 8/2. The value of [GlobalData getInstance] cannot be computed at compile-time, so it cannot be used to initialize the global variable.
Instead, you need to just use [GlobalData getInstance] inside your function bodies wherever you are currently trying to use the globDat variable.
As for the warning, Incomplete implementation, I don't see what's missing. Perhaps you didn't post all of the code from GlobalData.h. Anyway, you should be able to click the warning (where it appears on the right side of the editor window) and have Xcode show you what's missing.
This is the way I create my Singleton:
Singleton.h
#import <Foundation/Foundation.h>
#interface Singleton : NSObject {
NSMutableArray *firstMutableArray;
NSMutableArray *secondMutableArray;
}
#property (nonatomic, retain) NSMutableArray *firstMutableArray;
#property (nonatomic, retain) NSMutableArray *secondMutableArray;
+ (id)sharedSingleton;
#end
Sigleton.m
#import "Singleton.h"
static Singleton *sharedMySingleton = nil;
#implementation Singleton
#synthesize firstMutableArray;
#synthesize secondMutableArray;
#pragma mark Singleton Methods
+ (id)sharedSingleton {
#synchronized(self) {
if (sharedMySingleton == nil) {
sharedMySingleton = [[super allocWithZone:NULL] init];
}
return sharedMySingleton;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedSingleton] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX;
}
- (oneway void)release {
// Never release
}
- (id)autorelease {
return self;
}
- (id)init {
if (self = [super init]) {
firstMutableArray = [[NSMutableArray alloc] initWithObjects:nil];
secondMutableArray = [[NSMutableArray alloc] initWithObjects:nil];
}
return self;
}
- (void)dealloc {
[firstMutableArray release];
[secondMutableArray release];
[super dealloc];
}
#end
Then, when you want to call your Singleton:
#import "Singleton.h"
Singleton *singleton = [Singleton sharedSingleton];
singleton.firstMutableArray = ...
singleton.secondMutableArray = ...

Override #synthesize method?

I have one class called dog and another class called cat.
Dog has an variable, "name" declared with #property in the .h file.
In the cat class, I have set the name by using the command, myDog.name = "buster", after creating the variable "myDog" of type dog.
I would like to do additional operations when the name is set by overriding the set method normally created by the #synthesize command.
How can I do that? Thanks for the help!
All you have to do is leave the #synthesize then create whichever methods you want to be custom. Example:
In .h
#property(nonatomic, retain)NSString *Bob;
In .m
#synthesize bob;
-(void)setBob:(NSString *)bobValue{
[bobValue retain];
[bob release];
bob = bobValue;
//your custom stuffs here
}
This has been pretty much answered on SO already - see Objective-C synthesize property name overriding for details. In particular, #Dev Kanchen's answer which includes example code.
You cannot override (and call it within) a synthesized method from within the very same class.
You can however override it from a subclass (or rather: synthesize it in an abstract superclass).
If you simply want to perform additional (vs. different) operations upon property change I would use KVO by simply adding each dog as observer to its own "name" property in -(id)init;.
Edit:
There is a way to add additional logic to synthesized methods from within the same class:
Define a private intermediate property in a class extension.
I've attached source code for a class which uses synthesized properties and takes care(sic!) of keeping the dog's owner in sync with its own identity.
Dog.h:
#import <Foundation/Foundation.h>
#interface Dog : NSObject {
#private
NSString *name;
NSString *owner;
}
#property (nonatomic, readwrite, retain) NSString *name;
#property (nonatomic, readwrite, retain) NSString *owner;
#end
Dog.m:
#import "Dog.h"
#interface Dog ()
#property (nonatomic, readwrite, retain) NSString *primitiveName;
#end
#implementation Dog
#dynamic name;
#synthesize primitiveName = name;
#synthesize owner;
- (id)init {
if ((self = [super init])) {
name = #"Snowy";
owner = #"Tintin";
}
return self;
}
- (void)dealloc {
[super dealloc];
}
- (NSString *)name {
return self.primitiveName;
}
- (void)setName:(NSString *)aName {
self.primitiveName = aName;
if ([aName isEqualToString:#"Snoopy"]) {
self.owner = #"Charlie Brown";
}
else if ([aName isEqualToString:#"Snowy"]) {
self.owner = #"Tintin";
}
}
- (NSString *)description {
return [NSString stringWithFormat:#"<%# name:'%#' owner:'%#'>", [self class], self.name, self.owner];
}
#end
Test:
Dog *dog = [[Dog alloc] init];
NSLog(#"%#", dog);
dog.name = #"Snoopy";
NSLog(#"%#", dog);
dog.name = #"Snowy";
NSLog(#"%#", dog);
Result:
<Dog name:'Snowy' owner:'Tintin'>
<Dog name:'Snoopy' owner:'Charlie Brown'>
<Dog name:'Snowy' owner:'Tintin'>