Re: Releasing properties?

2016-08-27 Thread じょいすじょん

> On 2016 Aug 27, at 23:31, Keary Suska  wrote:
> 
> 
>> On Aug 27, 2016, at 8:22 AM, じょいすじょん  
>> wrote:
>> 
>> 
>>> On 2016 Aug 27, at 23:09, Keary Suska  wrote:
>>> 
 
 On Aug 27, 2016, at 5:22 AM, Andreas Falkenhahn  
 wrote:
 
 Consider the following example properties:
 
  NSApplication: @property(strong) NSMenu *mainMenu
  NSFont: @property(readonly, copy) NSString *familyName
  NSColorPanel: @property(copy) NSColor *color
 
 AFAIU I must not release the NSMenu/NSString/NSColor obtained from these
 properties because I don't own the objects returned by those properties and
 Apple's memory management policy docs clearly say:
 
  "You must not relinquish ownership of an object you do not own"
 
 So I think I've got that right but I'd be glad if somebody could just
 confirm that I got it right ;)
 
 I'm just a little confused because of the keywords "strong" and "copy" in
 the @property declarations but AFAIU these only refer to setting those
 properties, not getting those properties, i.e. the object is copied when
 *setting* the property, not when *getting* it. Right?
 
 And another question: Can it also happen that a class has a property
 which returns an object which I *must* release or is it a general rule
 that getting a @property always returns objects which I do not own
 and hence mustn't released?
>>> 
>>> There are only specific method conventions that establish ownership: 
>>> alloc+init and new. This is because ownership should only be granted when 
>>> specifically requested by the caller. There is no good reason for an object 
>>> to require that a caller own a returned object. Now, some API could decide 
>>> to buck the convention and have a different object construction naming, but 
>>> the point is the same. If an API does anything else, it is badly designed. 
>>> Cocoa will never do this.
>>> 
>>> One could even argue (and some have) that there is no good reason for *any* 
>>> object method to return a retained object, as that forces the caller to 
>>> explicitly require ownership. And that is key: ownership is a function of 
>>> the caller, not the object.
>>> 
>>> HTH,
>>> 
>>> Keary Suska
>>> Esoteritech, Inc.
>>> "Demystifying technology for your home or business"
>>> 
>>> 
>> Just to keep everyone on the rules, I'm going to post the docs links.
>> It's too easy to quote it wrong. (not saying anybody did)
>> 
>> Objective-C
>> 
>> https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html
>> 
>> https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
>> 
>> Core Foundation (because you WILL use it at some point)
>> 
>> https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html
> 
> Doh! Forgot “copy”. Best to point to docs since they are clear and succinct.
> 
Easy to mess up :)


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Releasing properties?

2016-08-27 Thread Keary Suska

> On Aug 27, 2016, at 8:22 AM, じょいすじょん  
> wrote:
> 
> 
>> On 2016 Aug 27, at 23:09, Keary Suska  wrote:
>> 
>>> 
>>> On Aug 27, 2016, at 5:22 AM, Andreas Falkenhahn  
>>> wrote:
>>> 
>>> Consider the following example properties:
>>> 
>>>   NSApplication: @property(strong) NSMenu *mainMenu
>>>   NSFont: @property(readonly, copy) NSString *familyName
>>>   NSColorPanel: @property(copy) NSColor *color
>>> 
>>> AFAIU I must not release the NSMenu/NSString/NSColor obtained from these
>>> properties because I don't own the objects returned by those properties and
>>> Apple's memory management policy docs clearly say:
>>> 
>>>   "You must not relinquish ownership of an object you do not own"
>>> 
>>> So I think I've got that right but I'd be glad if somebody could just
>>> confirm that I got it right ;)
>>> 
>>> I'm just a little confused because of the keywords "strong" and "copy" in
>>> the @property declarations but AFAIU these only refer to setting those
>>> properties, not getting those properties, i.e. the object is copied when
>>> *setting* the property, not when *getting* it. Right?
>>> 
>>> And another question: Can it also happen that a class has a property
>>> which returns an object which I *must* release or is it a general rule
>>> that getting a @property always returns objects which I do not own
>>> and hence mustn't released?
>> 
>> There are only specific method conventions that establish ownership: 
>> alloc+init and new. This is because ownership should only be granted when 
>> specifically requested by the caller. There is no good reason for an object 
>> to require that a caller own a returned object. Now, some API could decide 
>> to buck the convention and have a different object construction naming, but 
>> the point is the same. If an API does anything else, it is badly designed. 
>> Cocoa will never do this.
>> 
>> One could even argue (and some have) that there is no good reason for *any* 
>> object method to return a retained object, as that forces the caller to 
>> explicitly require ownership. And that is key: ownership is a function of 
>> the caller, not the object.
>> 
>> HTH,
>> 
>> Keary Suska
>> Esoteritech, Inc.
>> "Demystifying technology for your home or business"
>> 
>> 
> Just to keep everyone on the rules, I'm going to post the docs links.
> It's too easy to quote it wrong. (not saying anybody did)
> 
> Objective-C
> 
> https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html
> 
> https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
> 
> Core Foundation (because you WILL use it at some point)
> 
> https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html

Doh! Forgot “copy”. Best to point to docs since they are clear and succinct.

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Releasing properties?

2016-08-27 Thread じょいすじょん

> On 2016 Aug 27, at 23:09, Keary Suska  wrote:
> 
>> 
>> On Aug 27, 2016, at 5:22 AM, Andreas Falkenhahn  
>> wrote:
>> 
>> Consider the following example properties:
>> 
>>   NSApplication: @property(strong) NSMenu *mainMenu
>>   NSFont: @property(readonly, copy) NSString *familyName
>>   NSColorPanel: @property(copy) NSColor *color
>> 
>> AFAIU I must not release the NSMenu/NSString/NSColor obtained from these
>> properties because I don't own the objects returned by those properties and
>> Apple's memory management policy docs clearly say:
>> 
>>   "You must not relinquish ownership of an object you do not own"
>> 
>> So I think I've got that right but I'd be glad if somebody could just
>> confirm that I got it right ;)
>> 
>> I'm just a little confused because of the keywords "strong" and "copy" in
>> the @property declarations but AFAIU these only refer to setting those
>> properties, not getting those properties, i.e. the object is copied when
>> *setting* the property, not when *getting* it. Right?
>> 
>> And another question: Can it also happen that a class has a property
>> which returns an object which I *must* release or is it a general rule
>> that getting a @property always returns objects which I do not own
>> and hence mustn't released?
> 
> There are only specific method conventions that establish ownership: 
> alloc+init and new. This is because ownership should only be granted when 
> specifically requested by the caller. There is no good reason for an object 
> to require that a caller own a returned object. Now, some API could decide to 
> buck the convention and have a different object construction naming, but the 
> point is the same. If an API does anything else, it is badly designed. Cocoa 
> will never do this.
> 
> One could even argue (and some have) that there is no good reason for *any* 
> object method to return a retained object, as that forces the caller to 
> explicitly require ownership. And that is key: ownership is a function of the 
> caller, not the object.
> 
> HTH,
> 
> Keary Suska
> Esoteritech, Inc.
> "Demystifying technology for your home or business"
> 
> 
Just to keep everyone on the rules, I'm going to post the docs links.
It's too easy to quote it wrong. (not saying anybody did)

Objective-C

https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Core Foundation (because you WILL use it at some point)

https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Releasing properties?

2016-08-27 Thread Keary Suska

> On Aug 27, 2016, at 5:22 AM, Andreas Falkenhahn  
> wrote:
> 
> Consider the following example properties:
> 
>NSApplication: @property(strong) NSMenu *mainMenu
>NSFont: @property(readonly, copy) NSString *familyName
>NSColorPanel: @property(copy) NSColor *color
> 
> AFAIU I must not release the NSMenu/NSString/NSColor obtained from these
> properties because I don't own the objects returned by those properties and
> Apple's memory management policy docs clearly say:
> 
>"You must not relinquish ownership of an object you do not own"
> 
> So I think I've got that right but I'd be glad if somebody could just
> confirm that I got it right ;)
> 
> I'm just a little confused because of the keywords "strong" and "copy" in
> the @property declarations but AFAIU these only refer to setting those
> properties, not getting those properties, i.e. the object is copied when
> *setting* the property, not when *getting* it. Right?
> 
> And another question: Can it also happen that a class has a property
> which returns an object which I *must* release or is it a general rule
> that getting a @property always returns objects which I do not own
> and hence mustn't released?

There are only specific method conventions that establish ownership: alloc+init 
and new. This is because ownership should only be granted when specifically 
requested by the caller. There is no good reason for an object to require that 
a caller own a returned object. Now, some API could decide to buck the 
convention and have a different object construction naming, but the point is 
the same. If an API does anything else, it is badly designed. Cocoa will never 
do this.

One could even argue (and some have) that there is no good reason for *any* 
object method to return a retained object, as that forces the caller to 
explicitly require ownership. And that is key: ownership is a function of the 
caller, not the object.

HTH,

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Releasing properties?

2016-08-27 Thread Andreas Falkenhahn
Consider the following example properties:

NSApplication: @property(strong) NSMenu *mainMenu
NSFont: @property(readonly, copy) NSString *familyName
NSColorPanel: @property(copy) NSColor *color

AFAIU I must not release the NSMenu/NSString/NSColor obtained from these
properties because I don't own the objects returned by those properties and
Apple's memory management policy docs clearly say:

"You must not relinquish ownership of an object you do not own"

So I think I've got that right but I'd be glad if somebody could just
confirm that I got it right ;)

I'm just a little confused because of the keywords "strong" and "copy" in
the @property declarations but AFAIU these only refer to setting those
properties, not getting those properties, i.e. the object is copied when
*setting* the property, not when *getting* it. Right?

And another question: Can it also happen that a class has a property
which returns an object which I *must* release or is it a general rule
that getting a @property always returns objects which I do not own
and hence mustn't released?

Thanks!

-- 
Best regards,
 Andreas Falkenhahn  mailto:andr...@falkenhahn.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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: UIViewController memory warnings | didReceiveMemoryWarning | setView | releasing outlets | releasing properties

2008-11-29 Thread Ashley Clark

On Nov 29, 2008, at 2:58 PM, Glenn Bloom wrote:

// Implement loadView if you want to create a view hierarchy  
programmatically

- (void)loadView {


/* snip */

	NSMutableString * stringCompleteMutable = [NSMutableString  
stringWithString:string00Local]; // local variable set with a  
constructor that handles release, so there will be no need to  
release it

[stringCompleteMutable appendString: @", "];
[stringCompleteMutable appendString: myStringA];
[stringCompleteMutable appendString: @", "];
[stringCompleteMutable appendString: self.myStringB];


This is fine and there's nothing wrong with it but it might be more  
readable to create your string with a format string:


	NSString *stringComplete = [NSString stringWithFormat:@"%@, %@, %@",  
string00Local, myStringA, self.myStringB];


That's really a stylistic point though, it's not like this code will  
be running in a loop generating hundreds of strings where you'd want  
to send as few messages as possible.



self.labelA.text = stringCompleteMutable;



[self.labelA setText:stringCompleteMutable];


These two lines are equivalent but I think it's just remnants of some  
copy and pasting though.



As I understand it, all instances of UIViewController will receive the  
didReceiveMemoryWarning message when the OS warns the app. At that  
point you should clear out any caches. Since they all receive this  
message, even if they're visible, you can't know at that point whether  
the view will be released or not. Currently the only way to know that  
your view is going away is when you receive a setView:nil message.  
It's at that point, when your view is being released, that you should  
also release and nil out any references you may have to objects that  
are part of that view.



// Method setView:
// Overrides setter for UIViewController property view.
- (void)setView:(UIView *)theView;
{
if (theView == nil){
// release views and label when the argument is nil
		// As long as this UIViewController subclass retains its top level  
view then all of the view's subviews will also be retained.   
However, they should all be released when the UIViewController  
releases its view... And we can't release them in method  
didReceiveMemoryWarning because... 1. MUST CONFIRM: we have declared  
them as properties, with "retain", and we can't determine accurately  
within didReceiveMemoryWarning when the view controller's view is in  
fact released (except by calling setView), so we can't conditionally  
release them within the didReceiveMemoryWarning method (except by  
actually setting the controller's view).

self.labelA = nil;
self.imageViewA = nil;  
self.subViewA = nil;

		self.primaryViewA = nil;  // We also release this here, not in  
didReceiveMemoryWarning, despite the fact that the controller's view  
is set to this rather than it be added to the controller's view as a  
subview. Since the view is going away here you need to remove all  
references to it, and in fact, must remove this reference  
specifically as it won't be dealloc'ed until you do since you've  
retained it.

}
[super setView:theView];
}// End Method setView:


- (void)didReceiveMemoryWarning {   

	// Release anything that's not essential, such as cached data  
(meaning instance variables, and what else...?)


	// Obviously can't access local variables such as defined in method  
loadView, so can't release them here


	// We can set some instance variables as nil, rather than call the  
release method on them, if we have defined setters that retain nil  
and release their old values (such as through use of @synthesize).  
This can be a better approach than using the release method, because  
this prevents a variable from pointing to random remnant data.  Note  
in contrast, that setting a variable directly (using "=" and not  
using the setter), would result in a memory leak.

self.myStringB = nil;


	 // Even though no setters were defined for this object, still set  
it to nil after releasing it for precisely the same reason that you  
set properties to nil.
	// Note that because myStringA was only set to point to a static  
string, it doesn't really need to be released here, but pedantically  
this is correct - this is good form, anticipating for instance, a  
modification by which this string ends up being later created  
through some other class in some other manner

[myStringA release], myStringA = nil;


// Releases the view if it doesn't have a superview
[super didReceiveMemoryWarning];
}




- (void)dealloc {

	// In contrast to how you deallocated in didReceiveMemoryWarning,  
in dealloc you don't want to employ setters. As a general rule, you  
don't want to employ setters in either init methods or in dealloc.   
Conceptually, gener

Re: UIViewController memory warnings | didReceiveMemoryWarning | setView | releasing outlets | releasing properties

2008-11-29 Thread Ashley Clark

On Nov 29, 2008, at 9:45 AM, Glenn Bloom wrote:


Ashley,

Can't thank you enough.  I just posted the following, hoping to pre- 
empt other folks from wasting time correcting me on various points  
you addressed - and I hope, refocusing things on my major  
questions.  I have of course been through the memory management  
documentation you referred me to, and much else on the subject, but  
clearly need to work through it all alot more. Will do so feverishly  
beginning now, but again, thought it best to fix what I could  
quickly in a revised post, to avoid wasting lots of folks time...   
Also I didn't see your response to me posted in the mailing list -  
so wasn't sure if/how I should give credit for your help?


Hmmm... I'm pretty sure that I cc'ed the list on that first email. I  
believe that if the list sees that a message already went to you it  
won't send it to you again though so that may explain why you didn't  
see it there. Oh well, no bother.


Unfortunately I still saw a couple of things that I don't think I made  
myself clear on earlier.



	NSString* string00Local = [[NSString alloc]  
initWithString:@"00"];	//Note: String constants, like @"abc", are  
specially generated by the compiler as static objects; release and  
retain have no effect on them.  So there will be no need to release  
string00Local
	myStringA = [[NSString alloc] initWithString:@"A"];// Note that  
myStringA is an instance variable but not a property, so can't call  
self.myStringA.  Will need to be released in dealloc


If your assignment statement were simply: NSString *string00Local =  
@"00"; then yes you wouldn't have to release it. What you're doing  
though is creating a new object based on the static string @"00". Any  
object created through an -init... type method is owned by you and  
would need to be released.


A @"something" constant is an object on its' own standing. You do not  
have to use it as a constant in creating an object. You'd probably  
only use it in an initWithString: message if you were creating a  
mutable string from it. I'd probably prefer [@"something" mutableCopy]  
though since it's more readable IMO.


	self.myStringB = [NSString stringWithFormat:@"B"]; // instance  
variable - must be released in dealloc. And note that not using  
"self", alternatively setting 'myStringB = ...' would be wrong - it  
would bypass your @synthesized accessors. In every method except for  
-init and -dealloc, accessing your properties via self.propertyName.


This isn't wrong from a memory management standpoint since the object  
returned from stringWithFormat: is then retained by the property. But  
it looks odd. I'd have simply set self.myStringB = @"B" directly like  
the others.


	myStringC = [NSString stringWithFormat:@"C"];// myStringC is an  
instance variable but not a property (so can't call  
self.myStringC).Will need to be released in dealloc


This would also need to be retained since you want the value to stay  
around. You're probably not seeing crashes on any of these because of  
how NSString conservatively creates objects. I'm relatively certain  
that if you were to create two objects, objectA = @"C" and objectB =  
[NSString stringWithFormat:@"C"] and compared their pointer value that  
they'd be equivalent. Really though that is an implementation detail  
and you should be simply assigning myStringC = @C";



I'm not sure if you intended to but you're creating two UILabel  
objects here.


	// See previous comment - same reasoning applies (use a temporary  
variable here as well).

UILabel *labelTemp = [[UILabel alloc]init];
	self.labelA = labelTemp;// instance variable - will be released in  
dealloc

[labelTemp release];


The first one was created in that stanza.

	CGRect rectA = CGRectMake(0,0, 320,50);// CGRect is a scalar  
structure that's local to the scope it's defined in. It has no  
concept of retain/release/autorelease, the same as NSInteger,  
NSUInteger, BOOL and CGFloat

self.labelA = [[UILabel alloc] initWithFrame:rectA];


Then you created another object here.



// Method setView:
// Overrides setter for UIViewController property view.
- (void)setView:(UIView *)theView;
{
if (theView == nil){
// release views and label when the argument is nil
		// As long as this UIViewController subclass retains its top level  
view then all of the view's subviews will also be retained.   
However, they should all be released when the UIViewController  
releases its view... And we can't release them in method  
didReceiveMemoryWarning because... 1. MUST CONFIRM: we have declared  
them as properties, with "retain", and we can't determine accurately  
within didReceiveMemoryWarning when the view controller's view is in  
fact released (except by calling setView), so we can't conditionally  
release them within the didReceiveMemoryWarning method (except by  
actually setting the controller's view).

self.labelA = ni

Re: UIViewController memory warnings | didReceiveMemoryWarning | setView | releasing outlets | releasing properties

2008-11-28 Thread Ashley Clark

On Nov 28, 2008, at 11:44 PM, Glenn Bloom wrote:

In the course of trying to understand UIViewController memory  
warnings on
the iPhone, I've found various useful threads online, and in  
particular, was
very glad to follow the numerous recent posts in this forum with the  
subject

'Outlets / IBOutlet declarations'.

In response, I've written a test app to confirm what I think I have  
gathered

so far. I will be very appreciative if anyone can take a look at the
interface and implementation below and respond to any of the five (5)
different comments tagged with "MUST CONFIRM".  I have also heavily
commented most everything else related to memory management (gone
overboard), thinking it relevant to this example, at least for folks  
like

myself, newer to the subject.

Essentially, what is below are an interface and implementation that  
modify

the iPhone View-Based Application template to display a UILabel and a
UIImage within a couple of nested views.  I define and work with  
different
instance variables and (local variables as well), solely for the  
point of

trying to compare what gets released/deallocated where and how...

Thanks to anyone in advance for any assistance.


I'll take a stab at it.



//
//  Test00ViewController.h
//  Test00
//

#import 

@interface Test00ViewController : UIViewController {

NSString *myStringA; // Will NOT be a property
NSString *myStringB;
NSString *myStringC; // Will NOT be a property
NSString *myStringD;

IBOutlet UIView *primaryViewA;
IBOutlet UIView *subViewA;
IBOutlet UILabel *labelA;
IBOutlet UIImageView *imageViewA;

}

@property (nonatomic, retain) NSString *myStringB;
@property (nonatomic, retain) NSString *myStringD;

// Note: For the iPhone, unless encountering a compelling reason not  
to do so, generally make outlets properties, and retain them.

@property (nonatomic, retain) UIView *primaryViewA;
@property (nonatomic, retain) UIView *subViewA;
@property (nonatomic, retain) UILabel *labelA;
@property (nonatomic, retain) UIImageView *imageViewA;

@end


I think the suggested syntax here is to move the IBOutlet tag to the  
@property line and out of the @interface section as well, for example


@property (nonatomic, retain) IBOutlet UIView *someView;



//
//  Test00ViewController.m
//  Test00
//

#import "Test00ViewController.h"

@implementation Test00ViewController

@synthesize myStringB;
@synthesize myStringD;

@synthesize primaryViewA;
@synthesize subViewA;
@synthesize labelA;
@synthesize imageViewA;



// Implement loadView if you want to create a view hierarchy  
programmatically

- (void)loadView {


You're leaking strings here.

NSString* string00 = [[NSString alloc] init];// local variable that  
will

need to be released locally


At this point, string00 is an empty string that you'll need to release.


string00 = @"00";


After this line, string00 is now pointing to a new string object and  
you've leaked the previous empty string object.



[string00 release];


String constants, like @"00", are specially generated by the compiler  
as static objects; release and retain have no effect on them.


NSString* string01 = [NSString string];// local variable set with a  
constructor that handles release, so there will be no need to  
release it

string01 = @"01";
myStringA = [[NSString alloc] init];// instance variable that will  
need to be released in dealloc

myStringA = @"A";


Same thing applies for string01 and myStringA here. Also it might be  
important to point out that setting your myStringA properties in this  
way bypasses your @synthesized accessors. In every method except for - 
init and -dealloc you should be accessing your properties via  
self.propertyName.


So your myStringA assignment should look like this:

self.myStringA = @"A";

myStringB = [NSString stringWithFormat:@"B"];// instance variable -  
must be released in dealloc, even though set with a constructor that  
handles release
myStringC = [NSString stringWithFormat:@"C"];// instance variable -  
must be released in dealloc, even though set with a constructor that  
handles release
myStringD = [NSString stringWithFormat:@"D"];// instance variable -  
must be released in dealloc, even though set with a constructor that  
handles release


In this case, since you're not using your accessor methods, you are  
not retaining these objects and when the autorelease pool is drained  
you'll be left with dangling references. Use your accessors.


NSMutableString * stringEMutable = [NSMutableString  
stringWithString:string00]; // local variable set with a constructor  
that handles release, so there will be no need to release it

[stringEMutable appendString: @", "];
[stringEMutable appendString: string01];
[stringEMutable appendString: @", "];
[stringEMutable appendString: myStringA];
[stringEMutable appendString: @", "];
[stringEMutable appendString: myStringB];
[stringEMutable appendString: @", "];
[stringEMutable appendString: myStringC];
[stringEMutable appendString: @", "]

UIViewController memory warnings | didReceiveMemoryWarning | setView | releasing outlets | releasing properties

2008-11-28 Thread Glenn Bloom
In the course of trying to understand UIViewController memory warnings on
the iPhone, I've found various useful threads online, and in particular, was
very glad to follow the numerous recent posts in this forum with the subject
'Outlets / IBOutlet declarations'.

In response, I've written a test app to confirm what I think I have gathered
so far. I will be very appreciative if anyone can take a look at the
interface and implementation below and respond to any of the five (5)
different comments tagged with "MUST CONFIRM".  I have also heavily
commented most everything else related to memory management (gone
overboard), thinking it relevant to this example, at least for folks like
myself, newer to the subject.

Essentially, what is below are an interface and implementation that modify
the iPhone View-Based Application template to display a UILabel and a
UIImage within a couple of nested views.  I define and work with different
instance variables and (local variables as well), solely for the point of
trying to compare what gets released/deallocated where and how...

Thanks to anyone in advance for any assistance.


//
//  Test00ViewController.h
//  Test00
//

#import 

@interface Test00ViewController : UIViewController {

NSString *myStringA; // Will NOT be a property
 NSString *myStringB;
NSString *myStringC; // Will NOT be a property
NSString *myStringD;

IBOutlet UIView *primaryViewA;
IBOutlet UIView *subViewA;
IBOutlet UILabel *labelA;
 IBOutlet UIImageView *imageViewA;

}

@property (nonatomic, retain) NSString *myStringB;
@property (nonatomic, retain) NSString *myStringD;

// Note: For the iPhone, unless encountering a compelling reason not to do
so, generally make outlets properties, and retain them.
@property (nonatomic, retain) UIView *primaryViewA;
@property (nonatomic, retain) UIView *subViewA;
@property (nonatomic, retain) UILabel *labelA;
@property (nonatomic, retain) UIImageView *imageViewA;

@end




//
//  Test00ViewController.m
//  Test00
//

#import "Test00ViewController.h"

@implementation Test00ViewController

@synthesize myStringB;
@synthesize myStringD;

@synthesize primaryViewA;
@synthesize subViewA;
@synthesize labelA;
@synthesize imageViewA;



// Implement loadView if you want to create a view hierarchy
programmatically
- (void)loadView {

NSString* string00 = [[NSString alloc] init];// local variable that will
need to be released locally
 string00 = @"00";
[string00 release];
NSString* string01 = [NSString string];// local variable set with a
constructor that handles release, so there will be no need to release it
 string01 = @"01";

 myStringA = [[NSString alloc] init];// instance variable that will need to
be released in dealloc
 myStringA = @"A";
myStringB = [NSString stringWithFormat:@"B"];// instance variable - must be
released in dealloc, even though set with a constructor that handles release
myStringC = [NSString stringWithFormat:@"C"];// instance variable - must be
released in dealloc, even though set with a constructor that handles release
myStringD = [NSString stringWithFormat:@"D"];// instance variable - must be
released in dealloc, even though set with a constructor that handles release

NSMutableString * stringEMutable = [NSMutableString
stringWithString:string00]; // local variable set with a constructor that
handles release, so there will be no need to release it
 [stringEMutable appendString: @", "];
[stringEMutable appendString: string01];
 [stringEMutable appendString: @", "];
[stringEMutable appendString: myStringA];
 [stringEMutable appendString: @", "];
[stringEMutable appendString: myStringB];
 [stringEMutable appendString: @", "];
[stringEMutable appendString: myStringC];
 [stringEMutable appendString: @", "];
[stringEMutable appendString: myStringD];
 printf("contents of stringEMutable: %s\n", [stringEMutable UTF8String]);
 primaryViewA = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]
applicationFrame]]; // instance variable - will be released in dealloc
primaryViewA.backgroundColor = [UIColor redColor];
 subViewA = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]
applicationFrame]]; // instance variable - will be released in dealloc
subViewA.backgroundColor = [UIColor greenColor];
 labelA = [[UILabel alloc]init];// instance variable - will be released in
dealloc
 CGRect rectA = CGRectMake(0,0, 320,50);// local variable set with a
constructor that handles release, so there will be no need to release it
labelA = [[UILabel alloc] initWithFrame:rectA];
 labelA.font = [UIFont systemFontOfSize:12.0];
labelA.textAlignment = UITextAlignmentCenter;
 labelA.text = stringEMutable;
labelA.textColor = [UIColor whiteColor];
labelA.backgroundColor = [UIColor blueColor];
 [labelA setText:stringEMutable];
[subViewA addSubview:labelA];
 CGRect imageRect;
UIImage *theImage;
 theImage = [UIImage imageNamed:@"Button00A.png"]; // local variable set
with a constructor that handles release, so there will be no need to release
it
 int w = theImage.size.width;
int h = th