Re: Solving memory leaks

2010-03-28 Thread Michael Davey

On 28 Mar 2010, at 02:14, Quincey Morris wrote:

 On Mar 27, 2010, at 16:51, Noah Desch wrote:
 
 If you are *not* using getters and setters but instead have myFields 
 declared as:
 
 @interface MyClass
 {
  NSMutableDictionary *myFields;
 }
 
 and you use the above line of code, and subsequently release myFields in 
 your dealloc method this would *not* be a memory leak, correct?
 
 Correct (except that the 'self.' syntax won't work.) The OP had exactly the 
 code pattern you describe:
 
   ...
   if (myFields == nil)
   myFields = [[NSMutableArray alloc] init];
   ...
 
   - (void) dealloc {
   [myFields release];
   ...
   }
 
 (The OP called it just 'fields'.) That's not a memory leak -- in the first 
 part, the MyClass object owns the array it creates (once), and it 
 relinquishes ownership in its 'dealloc' (once). There can only be a leak for 
 one of 3 reasons:
 
 1. Some other piece of code assigns a new value to 'myFields' without 
 releasing the old value.

That is the only part of my code that adds values to the field.

 
 2. Some other piece of code retains 'myFields', but never releases it.

I return the values as keys for an NSDictionary that is the database row.

 
 3. The MyClass object is itself leaked, so its dealloc is never called.

I shall try and find out if that is happening, but this was the heaviest hit in 
Instruments.

Is there any easy way to find out if this is happening?

M___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Klaus Backert


On 28 Mar 2010, at 18:40, Michael Davey wrote:

1. Some other piece of code assigns a new value to 'myFields'  
without releasing the old value.


That is the only part of my code that adds values to the field.


In order to handle your fields instance variable correctly, what do  
you think about the following:


Create fields in the init method of your MyClass object (I don't  
know how you call this class):


fields  = [[NSMutableDictionary alloc] init];

by which you retain the fields dictionary.

And destroy fields in the corresponding dealloc method:

[fields release];
fields = nil;

If you want to use the fields dictionary anywhere in your code, you  
just do only calls like:


[fields addObject: ...];
[fields removeObject: ...];
MyOtherObject *myOtherObject = [fields objectWithKey: ...];
etc.

but you do *not* invoke methods which initialize or dealloc the fields  
object.


Klaus

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Klaus Backert


On 28 Mar 2010, at 19:11, Klaus Backert wrote:


MyOtherObject *myOtherObject = [fields objectWithKey: ...];


Correction: objectForKey

Klaus

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Michael Davey
That would be gut for the fact that my fields are released and set to nil 
whenever a new SELECT query is executed - however, I think I can do this by 
emptying the array when a new query is done and just counting the size of the 
array in my fetch method - thanks...

On 28 Mar 2010, at 18:11, Klaus Backert wrote:

 
 On 28 Mar 2010, at 18:40, Michael Davey wrote:
 
 1. Some other piece of code assigns a new value to 'myFields' without 
 releasing the old value.
 
 That is the only part of my code that adds values to the field.
 
 In order to handle your fields instance variable correctly, what do you think 
 about the following:
 
 Create fields in the init method of your MyClass object (I don't know how 
 you call this class):
 
 fields  = [[NSMutableDictionary alloc] init];
 
 by which you retain the fields dictionary.
 
 And destroy fields in the corresponding dealloc method:
 
 [fields release];
 fields = nil;
 
 If you want to use the fields dictionary anywhere in your code, you just do 
 only calls like:
 
 [fields addObject: ...];
 [fields removeObject: ...];
 MyOtherObject *myOtherObject = [fields objectWithKey: ...];
 etc.
 
 but you do *not* invoke methods which initialize or dealloc the fields object.
 
 Klaus
 
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 http://lists.apple.com/mailman/options/cocoa-dev/frak.off%40gmail.com
 
 This email sent to frak@gmail.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Solving memory leaks

2010-03-28 Thread Michael Davey

 -(NSDictionary *)fetch {
   NSMutableDictionary *output = nil;
   if (db != nil  sth != nil) {
   int c = sqlite3_column_count(sth);
   if (fields == nil) {
   fields = [[NSMutableArray alloc] init];
   for (int i = 0; i  c; ++i) {
   const char *name = sqlite3_column_name(sth, i);
   [fields addObject:[NSString 
 stringWithUTF8String:name]];
   }
   }
   if (sqlite3_step(sth) == SQLITE_ROW) {
   output = [[[NSMutableDictionary alloc] init] 
 autorelease];
   for (int i = 0; i  c; ++i) {
   const unsigned char *val = 
 sqlite3_column_text(sth, i);
   NSString *value;
   if (val == nil) {
   value = @{NULL};
   }
   else {
   value = [NSString 
 stringWithUTF8String:(char *)val];
   }
   [output setObject:value forKey:[fields 
 objectAtIndex:i]];
   }
   }
   }
   return output;
 }

However, can anyone answer how I best go about either of the tasks that I have 
outlined as red, as they are leaking a lot of memory in 
comparison?___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread mmalc Crawford

On Mar 28, 2010, at 10:27 am, Michael Davey wrote:

 That would be gut for the fact that my fields are released and set to nil 
 whenever a new SELECT query is executed - however, I think I can do this by 
 emptying the array when a new query is done and just counting the size of the 
 array in my fetch method - thanks...
 
Why not follow what someone else suggested earlier in the thread, and the 
pattern that is recommended in the documentation, and use accessor methods. As 
soon as you start sprinkling retains and releases throughout your code, you're 
liable to make a mistake.
http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447


On Mar 28, 2010, at 10:37 am, Michael Davey wrote:

 However, can anyone answer how I best go about either of the tasks that I 
 have outlined as red, as they are leaking a lot of memory in comparison?
 

You best go about this by reading and understanding the memory management 
rules. There is no substitute for this. There really isn't much to them:

http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/2994

mmalc




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Klaus Backert


On 28 Mar 2010, at 19:27, Michael Davey wrote:

That would be gut for the fact that my fields are released and set  
to nil whenever a new SELECT query is executed - however, I think I  
can do this by emptying the array when a new query is done and just  
counting the size of the array in my fetch method - thanks...


emptying the array is among the etc. below ;-)

[fields removeAllObjects];

and, if you first add and then remove [all] correctly, then the  
balance between retain and release of the objects in the dictionary is  
not destroyed (not this way at least).



On 28 Mar 2010, at 18:11, Klaus Backert wrote:

...
In order to handle your fields instance variable correctly, what do  
you think about the following:


Create fields in the init method of your MyClass object (I don't  
know how you call this class):


fields  = [[NSMutableDictionary alloc] init];

by which you retain the fields dictionary.

And destroy fields in the corresponding dealloc method:

[fields release];
fields = nil;

If you want to use the fields dictionary anywhere in your code, you  
just do only calls like:


[fields addObject: ...];
[fields removeObject: ...];
MyOtherObject *myOtherObject = (MyOtherObject *)[fields  
objectForKey: ...];

etc.

but you do *not* invoke methods which initialize or dealloc the  
fields object.


Klaus

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Philip Mobley

On Mar 28, 2010, at 10:42 AM, mmalc Crawford wrote:

 That would be gut for the fact that my fields are released and set to nil 
 whenever a new SELECT query is executed - however, I think I can do this by 
 emptying the array when a new query is done and just counting the size of 
 the array in my fetch method - thanks...
 
 Why not follow what someone else suggested earlier in the thread, and the 
 pattern that is recommended in the documentation, and use accessor methods. 
 As soon as you start sprinkling retains and releases throughout your code, 
 you're liable to make a mistake.
 http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447

Plus when you use accessor, you can put in a call to your NSLog( ) and see 
exactly whats going on...

- (void)setFields:(NSMutableArray *)newFields {
NSLog( @-setFields, old fields value: %p with new value %p, fields, 
newFields );
[fields autorelease];
fields = [newFields mutableCopy];
}

When calling setFields, you are then responsible for releasing the newFields 
NSMutableArray you created in your sample code, because [newFields mutableCopy] 
increments the ref counter.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread mmalc Crawford

On Mar 28, 2010, at 11:03 am, Philip Mobley wrote:

 When calling setFields, you are then responsible for releasing the 
 newFields NSMutableArray you created in your sample code, because 
 [newFields mutableCopy] increments the ref counter.
 
This is not correct.

[newFields mutableCopy] returns a new object that you own, it does not 
increment the ref count.
You must relinquish ownership of the previous value because you're about to 
take possession of a new value.

mmalc

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Michael Davey
I cache the fields array on the first run so that the method is efficient - 
this is a generic SQLite db wrapper that may potentially be used to access 
1000s of rows, and it seems perfectly reasonable that I should be able to store 
the fields in between SELECTs


On 28 Mar 2010, at 19:04, Jack Carbaugh wrote:

 I'm trying to understand your code logic ...
 
 It looks as if you are running a query which returns a list of Fields ... 
 then the values for each of those fields.
 
 In the first IF below, you are grabbing the column names to use as keys ... 
 and assigning values for those keys in the 2nd IF.
 
 The fields should be local in scope to THIS METHOD only. Therefore, you 
 should release it after using it.
 
 if Fields is meant to be used by a tableview or something else, you can get 
 those keys from the output dictionary via allKeys ...
 
 so here is my suggested rewrite
 
 
 -(NSDictionary *)fetch {
  NSMutableDictionary *output = [[NSMutableDictionary alloc] init]; // local 
 only to this method, returned autoreleased
 NSMutableArray  *fields = [[NSMutableArray alloc] init];; // local only to 
 this method, only need to grab column names from a query
 
  if (db != nil  sth != nil) {
  int c = sqlite3_column_count(sth);
  for (int i = 0; i  c; ++i) {
  const char *name = sqlite3_column_name(sth, i);
  [fields addObject:[NSString stringWithUTF8String:name]];
  }
  if (sqlite3_step(sth) == SQLITE_ROW) {
  for (int i = 0; i  c; ++i) {
  const unsigned char *val = sqlite3_column_text(sth, i);
  NSString *value;
  if (val == nil) {
  value = @{NULL};
  }
  else {
  value = [NSString stringWithUTF8String:(char *)val];
  }
  [output setObject:value forKey:[fields objectAtIndex:i]];
  }
  }
  }
 // fields no longer needed, so release
 [fields release];
  return [output autorelease];
 }
 
 
 However, can anyone answer how I best go about either of the tasks that I 
 have outlined as red, as they are leaking a lot of memory in 
 comparison?___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 http://lists.apple.com/mailman/options/cocoa-dev/intrntmn%40aol.com
 
 This email sent to intrn...@aol.com
 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-28 Thread Michael Davey
 OK, thanks for the links, and the help - I am going to read through and apply 
what I have learned to my code, I have already managed to fix two other leaks 
as a result of what I have learned.

Thank you.

On 28 Mar 2010, at 19:03, Philip Mobley wrote:

 
 On Mar 28, 2010, at 10:42 AM, mmalc Crawford wrote:
 
 That would be gut for the fact that my fields are released and set to nil 
 whenever a new SELECT query is executed - however, I think I can do this by 
 emptying the array when a new query is done and just counting the size of 
 the array in my fetch method - thanks...
 
 Why not follow what someone else suggested earlier in the thread, and the 
 pattern that is recommended in the documentation, and use accessor methods. 
 As soon as you start sprinkling retains and releases throughout your code, 
 you're liable to make a mistake.
 http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447
 
 Plus when you use accessor, you can put in a call to your NSLog( ) and see 
 exactly whats going on...
 
 - (void)setFields:(NSMutableArray *)newFields {
   NSLog( @-setFields, old fields value: %p with new value %p, fields, 
 newFields );
   [fields autorelease];
   fields = [newFields mutableCopy];
 }
 
 When calling setFields, you are then responsible for releasing the 
 newFields NSMutableArray you created in your sample code, because 
 [newFields mutableCopy] increments the ref counter.
 
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 http://lists.apple.com/mailman/options/cocoa-dev/frak.off%40gmail.com
 
 This email sent to frak@gmail.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Solving memory leaks

2010-03-27 Thread Michael Davey
Hi!

I have been running my iPhone application through the Leaks Instrument in an 
attempt to further understand what I have been coding, however, I fear I do not 
know enough about how retain/release work to be able to fix my leaks, and I was 
wondering if I could paste one trouble spot function that I have identified, 
and if someone could be so kind as to point out how I can fix the leaks and how 
to code them out in the future?

My function returns a row from a SQLite database as an NSDictionary, and is as 
follows:

-(NSDictionary *)fetch {
NSMutableDictionary *output = nil;
if (db != nil  sth != nil) {
int c = sqlite3_column_count(sth);
if (fields == nil) {
fields = [[NSMutableArray alloc] init];
for (int i = 0; i  c; ++i) {
const char *name = sqlite3_column_name(sth, i);
[fields addObject:[NSString 
stringWithUTF8String:name]];
}
}
if (sqlite3_step(sth) == SQLITE_ROW) {
output = [[[NSMutableDictionary alloc] init] 
autorelease];
for (int i = 0; i  c; ++i) {
const unsigned char *val = 
sqlite3_column_text(sth, i);
NSString *value;
if (val == nil) {
value = @{NULL};
}
else {
value = [NSString 
stringWithUTF8String:(char *)val];
}
[output setObject:value forKey:[fields 
objectAtIndex:i]];
}
}
}
return output;
}

The first leak reported by instruments is on the line where I alloc and init 
fields as an NSMutable array.  Firstly, fields is declared in my header, and is 
released in my dealloc method, so I am unsure what I have missed here and would 
be glad for any pointers on this problem.

The second is reported in the following line:

[fields addObject:[NSString stringWithUTF8String:name]];

Now, I can see that there is an anonymous string being created, but I am 
totally unsure as to how I can avoid leaking memory right here?

The third leak reported is here:

output = [[[NSMutableDictionary alloc] init] autorelease];

Now, I thought by using autorelease I was able to sidestep the issue of 
releasing this object (and I am pretty sure that adding this help fix an error 
that clang reported - could this be a false positive?)

And the last error is where I create the NSString value from the char *val - I 
believe this to be a similar class of error as my second leak, and would 
probably be addressed in a similar fashion.

So, sorry for such a lengthy email, and for asking so much of someone's time, 
but I hope that by seeing where I am going wrong here, I will be able to adopt 
good practices early on and make my code more robust in the future.

Many thanks to the poor soul who has to teach me the error of my ways in 
advance :o)

Mikey___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Michael Davey
So, you are saying I should call a retain when I get my reference so that it is 
kept as an instance var?

On 27 Mar 2010, at 19:33, Sandor Szatmari wrote:

 Every time this method runs you would loose the reference to the memory 
 previously allocated for the fields array.  This happens when you assign a 
 newly allocated array to feilds.
 
 You should either release fields before  reassigning it (conditionally if it 
 is not nil), or do not reallocate memory for it, instead empty it and reuse 
 the existing memory.
 
 Sandor Szatmari
 
 On Mar 27, 2010, at 15:06, Michael Davey frak@gmail.com wrote:
 
 Hi!
 
 I have been running my iPhone application through the Leaks Instrument in an 
 attempt to further understand what I have been coding, however, I fear I do 
 not know enough about how retain/release work to be able to fix my leaks, 
 and I was wondering if I could paste one trouble spot function that I have 
 identified, and if someone could be so kind as to point out how I can fix 
 the leaks and how to code them out in the future?
 
 My function returns a row from a SQLite database as an NSDictionary, and is 
 as follows:
 
 -(NSDictionary *)fetch {
   NSMutableDictionary *output = nil;
   if (db != nil  sth != nil) {
   int c = sqlite3_column_count(sth);
   if (fields == nil) {
   fields = [[NSMutableArray alloc] init];
   for (int i = 0; i  c; ++i) {
   const char *name = sqlite3_column_name(sth, i);
   [fields addObject:[NSString stringWithUTF8String:name]];
   }
   }
   if (sqlite3_step(sth) == SQLITE_ROW) {
   output = [[[NSMutableDictionary alloc] init] autorelease];
   for (int i = 0; i  c; ++i) {
   const unsigned char *val = sqlite3_column_text(sth, i);
   NSString *value;
   if (val == nil) {
   value = @{NULL};
   }
   else {
   value = [NSString stringWithUTF8String:(char *)val];
   }
   [output setObject:value forKey:[fields objectAtIndex:i]];
   }
   }
   }
   return output;
 }
 
 The first leak reported by instruments is on the line where I alloc and init 
 fields as an NSMutable array.  Firstly, fields is declared in my header, and 
 is released in my dealloc method, so I am unsure what I have missed here and 
 would be glad for any pointers on this problem.
 
 The second is reported in the following line:
 
 [fields addObject:[NSString stringWithUTF8String:name]];
 
 Now, I can see that there is an anonymous string being created, but I am 
 totally unsure as to how I can avoid leaking memory right here?
 
 The third leak reported is here:
 
 output = [[[NSMutableDictionary alloc] init] autorelease];
 
 Now, I thought by using autorelease I was able to sidestep the issue of 
 releasing this object (and I am pretty sure that adding this help fix an 
 error that clang reported - could this be a false positive?)
 
 And the last error is where I create the NSString value from the char *val - 
 I believe this to be a similar class of error as my second leak, and would 
 probably be addressed in a similar fashion.
 
 So, sorry for such a lengthy email, and for asking so much of someone's 
 time, but I hope that by seeing where I am going wrong here, I will be able 
 to adopt good practices early on and make my code more robust in the future.
 
 Many thanks to the poor soul who has to teach me the error of my ways in 
 advance :o)
 
 Mikey___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 http://lists.apple.com/mailman/options/cocoa-dev/admin.szatmari.net%40gmail.com
 
 This email sent to admin.szatmari@gmail.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Klaus Backert


On 27 Mar 2010, at 21:31, Michael Davey wrote:

So, you are saying I should call a retain when I get my reference so  
that it is kept as an instance var?


On 27 Mar 2010, at 19:33, Sandor Szatmari wrote:

Every time this method runs you would loose the reference to the  
memory previously allocated for the fields array.  This happens  
when you assign a newly allocated array to feilds.


You should either release fields before  reassigning it  
(conditionally if it is not nil), or do not reallocate memory for  
it, instead empty it and reuse the existing memory.


Assuming fields is an instance variable of some object, you could --  
or even should -- access it not directly but via getters and setters,  
which do memory management according to the rules, e.g. something like  
this (caution: typed in mail, etc.)


@interface MyClass
{
NSMutableDictionary *fields;
}
@property (retain) NSMutableDictionary *myFields;
@end

@implementation MyClass
@synthesize myFields = fields;
...
- (NSDictionary *)fetch
{
...
self.myFields = [[NSMutableArray alloc] init];
...
}
@end

regards
Klaus

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Quincey Morris
On Mar 27, 2010, at 14:11, Klaus Backert wrote:

 something like this (caution: typed in mail, etc.)


Yeah, something like this, but *not* this:

   self.myFields = [[NSMutableArray alloc] init];

That's a memory leak right there. :)

Incidentally, I think the OP was mistakenly interpreting Instruments as 
indicating the point of the leak. Instruments was indicating the place where 
the leaked object was originally created, which is likely *not* the point of 
the error. (In fact, there usually isn't a point where the leak occurs -- it 
occurs because some necessary 'release' was omitted.)


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Michael Davey

On 27 Mar 2010, at 22:16, Quincey Morris wrote:

 On Mar 27, 2010, at 14:11, Klaus Backert wrote:
 
 something like this (caution: typed in mail, etc.)
 
 
 Yeah, something like this, but *not* this:
 
  self.myFields = [[NSMutableArray alloc] init];
 
 That's a memory leak right there. :)
 
 Incidentally, I think the OP was mistakenly interpreting Instruments as 
 indicating the point of the leak. Instruments was indicating the place where 
 the leaked object was originally created, which is likely *not* the point of 
 the error. (In fact, there usually isn't a point where the leak occurs -- it 
 occurs because some necessary 'release' was omitted.)

So, how do I go about finding this place?

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Noah Desch



  but *not* this:

 self.myFields = [[NSMutableArray alloc] init];
 
 That's a memory leak right there. :)


This discussion is confusing me a bit... lets see if I got this right:

If you are *not* using getters and setters but instead have myFields declared 
as:

@interface MyClass
{
NSMutableDictionary *myFields;
}

and you use the above line of code, and subsequently release myFields in your 
dealloc method this would *not* be a memory leak, correct?

-Noah___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Keary Suska
On Mar 27, 2010, at 5:39 PM, Michael Davey wrote:

 On 27 Mar 2010, at 22:16, Quincey Morris wrote:
 
 On Mar 27, 2010, at 14:11, Klaus Backert wrote:
 
 something like this (caution: typed in mail, etc.)
 
 
 Yeah, something like this, but *not* this:
 
 self.myFields = [[NSMutableArray alloc] init];
 
 That's a memory leak right there. :)
 
 Incidentally, I think the OP was mistakenly interpreting Instruments as 
 indicating the point of the leak. Instruments was indicating the place where 
 the leaked object was originally created, which is likely *not* the point of 
 the error. (In fact, there usually isn't a point where the leak occurs -- it 
 occurs because some necessary 'release' was omitted.)
 
 So, how do I go about finding this place?

As Quincey said, there may not be any place, since it could be an *omission* of 
a release. However, if you are not using a setter, and you are properly 
releasing the ivar in dealloc, chances are there is a second assignment to 
myFields somewhere in your code that is invalidating a previous one. Are you 
perhaps setting it to nil at some point but not releasing it?

Keary Suska
Esoteritech, Inc.
Demystifying technology for your home or business

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Quincey Morris
On Mar 27, 2010, at 16:51, Noah Desch wrote:

 If you are *not* using getters and setters but instead have myFields declared 
 as:
 
 @interface MyClass
 {
   NSMutableDictionary *myFields;
 }
 
 and you use the above line of code, and subsequently release myFields in your 
 dealloc method this would *not* be a memory leak, correct?

Correct (except that the 'self.' syntax won't work.) The OP had exactly the 
code pattern you describe:

...
if (myFields == nil)
myFields = [[NSMutableArray alloc] init];
...

- (void) dealloc {
[myFields release];
...
}

(The OP called it just 'fields'.) That's not a memory leak -- in the first 
part, the MyClass object owns the array it creates (once), and it relinquishes 
ownership in its 'dealloc' (once). There can only be a leak for one of 3 
reasons:

1. Some other piece of code assigns a new value to 'myFields' without releasing 
the old value.

2. Some other piece of code retains 'myFields', but never releases it.

3. The MyClass object is itself leaked, so its dealloc is never called.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Klaus Backert


On 27 Mar 2010, at 23:16, Quincey Morris wrote:


On Mar 27, 2010, at 14:11, Klaus Backert wrote:


something like this (caution: typed in mail, etc.)



Yeah, something like this, but *not* this:


self.myFields = [[NSMutableArray alloc] init];


That's a memory leak right there. :)


Yes, sorry, and shame on me; too fast, too erroneous. The alloc-init  
retains and is not balanced by a release.


Klaus

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Solving memory leaks

2010-03-27 Thread Michael Davey
Thank you all so much for your responses - I will give them much better 
attention tomorrow, and sober :o)

On 28 Mar 2010, at 02:23, Klaus Backert wrote:

 
 On 27 Mar 2010, at 23:16, Quincey Morris wrote:
 
 On Mar 27, 2010, at 14:11, Klaus Backert wrote:
 
 something like this (caution: typed in mail, etc.)
 
 
 Yeah, something like this, but *not* this:
 
 self.myFields = [[NSMutableArray alloc] init];
 
 That's a memory leak right there. :)
 
 Yes, sorry, and shame on me; too fast, too erroneous. The alloc-init retains 
 and is not balanced by a release.
 
 Klaus
 
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 http://lists.apple.com/mailman/options/cocoa-dev/frak.off%40gmail.com
 
 This email sent to frak@gmail.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com