Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 8, 2011, 03:48 PM   #1
ksiedzulek
macrumors newbie
 
Join Date: Jan 2011
Obj-c, RetainCount problem

hi,

I am learning obj-c. I know that dealloc automatically start to operate when retain count reaches 0. Im my code [obiektos RetainCount] return 1, but dealloc is called (personally I've thought that [obiektos RetainCount] will return 0 and that's why dealloc is called).

why there is 1, not 0 at output?

output:

2011-04-08 21:19:27.853 Metoda prostokta[20729:a0f] zadzialal dealloc
2011-04-08 21:19:27.869 Metoda prostokta[20729:a0f] 1




Code:
#import "nowycos.h"
//#import "ojej.h"


int main (int argc, const char * argv[]) {
	nowycos*obiektos;
	nowycos*obiektos1;
	
	obiektos=[nowycos new];
	[obiektos release];


	NSLog(@"%d", [obiektos retainCount]);
    
	
	
	
	return 0;
}
here is dealloc:
Code:
-(void) dealloc
{
	NSLog(@"zadzialal dealloc");
	[super dealloc];
}
ksiedzulek is offline   0 Reply With Quote
Old Apr 8, 2011, 04:11 PM   #2
Catfish_Man
macrumors 68030
 
Catfish_Man's Avatar
 
Join Date: Sep 2001
Location: Portland, OR
Send a message via AIM to Catfish_Man
When the retain count *would* reach zero, *instead* -dealloc is called. There's no point in changing the number just before getting rid of the object.


More generally, it's almost never a good idea to call -retainCount. It will lie to you in many many situations. Follow the memory management rules, use the analyzer, and investigate problems with Instruments, and you should be good.
Catfish_Man is offline   0 Reply With Quote
Old Apr 8, 2011, 04:31 PM   #3
chown33
macrumors 603
 
Join Date: Aug 2009
After the last release of any object, the object itself is invalid.

Calling any method on an invalid object has an undefined result.

So expecting retainCount to be valid for an invalid object is nonsense.

If you ask a person you've just killed "Are you dead?", you should not expect them to say "Yes". You should not expect them to say "No", either. Any expectation of an answer is misinformed about the side-effects of death.
chown33 is offline   0 Reply With Quote
Old Apr 8, 2011, 04:34 PM   #4
ChOas
macrumors regular
 
Join Date: Nov 2006
Location: The Netherlands
You count, your objects don't... don't ask them for their count

Don't use retainCount (for your example).

[edit]
what chown33 just said
ChOas is offline   0 Reply With Quote
Old Apr 8, 2011, 05:34 PM   #5
GorillaPaws
macrumors 6502a
 
GorillaPaws's Avatar
 
Join Date: Oct 2003
Location: Richmond, VA
Quote:
Originally Posted by chown33 View Post
If you ask a person you've just killed "Are you dead?", you should not expect them to say "Yes". You should not expect them to say "No", either. Any expectation of an answer is misinformed about the side-effects of death.
Answers like these make me sad that Macrumors doesn't support voting up answers. Thanks for the laugh.
__________________
How to ask good programming questions: Getting Answers
GorillaPaws is offline   0 Reply With Quote
Old Apr 8, 2011, 07:43 PM   #6
holmesf
macrumors 6502a
 
Join Date: Sep 2001
Quote:
Originally Posted by chown33 View Post
After the last release of any object, the object itself is invalid.

Calling any method on an invalid object has an undefined result.

So expecting retainCount to be valid for an invalid object is nonsense.

If you ask a person you've just killed "Are you dead?", you should not expect them to say "Yes". You should not expect them to say "No", either. Any expectation of an answer is misinformed about the side-effects of death.
I love your answer.
holmesf is offline   0 Reply With Quote
Old Apr 8, 2011, 10:28 PM   #7
PatrickCocoa
macrumors 6502a
 
Join Date: Dec 2008
I'm Dead!

Quote:
Originally Posted by ksiedzulek View Post
[CODE]
#import "nowycos.h"
//#import "ojej.h"


int main (int argc, const char * argv[]) {
nowycos*obiektos;
nowycos*obiektos1;

obiektos=[nowycos new];
[obiektos release];

------------> obiektos is dead(ish), it will no longer reply coherently.
------------> Cocoa's run loop may or may not kill it at any point.

NSLog(@"%d", [obiektos retainCount]);




return 0;
}
As per chown, at the point of "----->", all references to obiektos are invalid.
__________________
iMac 21.5", 3.06GHz, 4 GB, 2 TB HD.
iPod Touch 3G.
PatrickCocoa is offline   0 Reply With Quote
Old Apr 9, 2011, 06:16 AM   #8
ksiedzulek
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
thanks for quick reply!

...but i still don't get it:/. I can "forget" about using retaincount, but that's not explain to me what happen here(please look at red code):

Code:
#import <Foundation/Foundation.h>
@interface SubObject : NSObject
{
	int x;
	int y;
}
@property int x,y;
@end

@implementation SubObject
-(void) dealloc
{
	NSLog(@"dealloc called");
	[super dealloc];
}
@synthesize x,y;
@end

@interface PrimObject: NSObject
{
	int szer;
	int wys;
	SubObject*mySubObject;
}
@property int szer,wys;
-(void) setMySubObject: (SubObject*) nobject;
-(SubObject*) mySubObject;
@end

@implementation PrimObject
@synthesize szer,wys;
-(SubObject*) mySubObject
{
	return mySubObject;
}
	
-(void) setMySubObject: (SubObject*) nobject
{
	mySubObject=nobject;
}
@end





int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	SubObject*thisIsSubObject=[SubObject new];
	[thisIsSubObject setX:6];
	PrimObject*Object=[PrimObject new];
	NSMutableArray *myarray=[NSMutableArray arrayWithCapacity:10];
	NSLog(@"retain number: %d", [thisIsSubObject retainCount]);
	[myarray addObject:thisIsSubObject];
	NSLog(@"retain number: %d", [thisIsSubObject retainCount]);
	[Object setMySubObject: thisIsSubObject];
	NSLog(@"retain number: %d", [thisIsSubObject retainCount]);

	[thisIsSubObject release];
	[thisIsSubObject release];// here is dealloc called
	
	[thisIsSubObject setX:7];// so why I can still set this?
	
	
	NSLog(@"number is: %d", Object.mySubObject.x);
	

	
   
    [pool drain];
    return 0;
}

here is output:
2011-04-09 12:08:05.992 hum[2021:a0f] retain number: 1
2011-04-09 12:08:05.994 hum[2021:a0f] retain number: 2
2011-04-09 12:08:05.995 hum[2021:a0f] retain number: 2
2011-04-09 12:08:05.995 hum[2021:a0f] dealloc called
2011-04-09 12:08:05.996 hum[2021:a0f] number is: 7

why do I can set "7"?

p.s. why "-(void) setMySubObject: (SubObject*) nobject;" doesn't increase retain number?
ksiedzulek is offline   0 Reply With Quote
Old Apr 9, 2011, 07:38 AM   #9
jiminaus
macrumors 65816
 
Join Date: Dec 2010
Location: Sydney
Quote:
Originally Posted by ksiedzulek View Post
p.s. why "-(void) setMySubObject: (SubObject*) nobject;" doesn't increase retain number?
Because you never call retain. All you do is assign the pointer. You might want to read carefully the Accessor Methods chapter of the Memory Management Programming Guide.

Or better yet, don't implement the methods yourself. Instead synthesise them.

Code:
@interface PrimObject: NSObject
{
	int szer;
	int wys;
	SubObject*mySubObject;
}
@property int szer,wys;
@property (retain) SubObject *mySubObject;
@end

@implementation PrimObject
@synthesize szer,wys,mySubObject;
@end
In regards to being able to set X after dealloc, this is just because the freed memory hasn't been reused/overwritten yet, so the object still seems to exist.

Take the analogy of deleting a file. When you delete a file, the bytes still exist on the disk, until they get overwritten by another file. If you knew where the file was on the disk (that is you had a pointer to that part of the disk), you could still access that file as though it hadn't been deleted. But eventually that part of the disk would be reused/overwritten by another file, and you could not longer access successfully.

The same is happening here with the memory for the object. You have what's called a dangling pointer. The bytes of the object still exists in memory and so you're still able to use it. But if you tried to use that pointer later in the program after many other objects had been created, chances are that the memory would have been overwritten by another object, and your attempt to set X would either fail (if you're lucky) or corrupt whatever object was now occupying that memory (which more likely).
jiminaus is offline   0 Reply With Quote
Old Apr 9, 2011, 09:05 AM   #10
ksiedzulek
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
thx Jiminaus! I've thooght a lot about it and my conclusions are same as your explanation. thx a lot
ksiedzulek is offline   0 Reply With Quote
Old Apr 9, 2011, 09:11 AM   #11
gnasher729
In Time-Out
 
Join Date: Nov 2005
Quote:
Originally Posted by ksiedzulek View Post
thanks for quick reply!

...but i still don't get it:/. I can "forget" about using retaincount, but that's not explain to me what happen here(please look at red code)
You _must_ forget about retainCount. Instead you _must_ read and understand the "Memory Management Programming Guide.".

The principle is that every unit of code has to do the right thing as far as retain / release is concerned and must not worry about what other bits are doing.

You used an NSMutableArray. NSArrays, mutable or not, retain things you put into the array, and release them when the array itself is deallocated. So the array itself does the right thing and doesn't care about what other code is doing.

When you implement a property like "mySubObject", you as the programmer must do the right thing. That is, you must retain the object when it is stored, you must release an object that was stored there previously, and you must release the object when the owner object is deallocated. Easiest done by synthesizing a property with "retain", and adding a "release" for the object to your dealloc.

The second "[thisIsSubObject release]" creates a time bomb. Your code has allocated the object (alloc = retained once) and released it twice, once more than it should have. So that part of code is wrong. Other bits of code might be retaining the object, so any problems might not occur _yet_. But they will occur, for example when the NSMutableArray is dealloc'ed.

And a crash is _not guaranteed_ to happen. You should assume that any wrong code will not bite you when you are just playing with it, it will bite you when it really, really hurts. When you ask "why does my incorrect code work?", the answer is "because it wants to lull you into a false sense of security in order to cause maximum damage".
gnasher729 is offline   0 Reply With Quote
Old Apr 9, 2011, 10:40 AM   #12
ksiedzulek
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
I think I start to feel it!

...but one more question, this time about autorelease pool.
here is a code (and question below):

Code:
#import <Foundation/Foundation.h>
@interface SubObject : NSObject
{
	int x;
	int y;
}
@property int x,y;
@end

@implementation SubObject
-(void) dealloc
{
	NSLog(@"dealloc called");
	[super dealloc];
}
@synthesize x,y;
@end

@interface PrimObject: NSObject
{
	int szer;
	int wys;
	SubObject*mySubObject;
}
@property int szer,wys;
-(void) setMySubObject: (SubObject*) nobject;
-(SubObject*) mySubObject;
@end

@implementation PrimObject
@synthesize szer,wys;
-(void) dealloc
{
	NSLog(@"dealloc called");
	[super dealloc];
}


-(SubObject*) mySubObject
{
	return mySubObject;
}

-(void) setMySubObject: (SubObject*) nobject
{
	mySubObject=nobject;
}
@end





int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	PrimObject*Object=[PrimObject new];
	SubObject*thisIsSubObject=[SubObject new];
	
		
	NSMutableArray *myarray=[NSMutableArray arrayWithCapacity:10];
	NSLog(@"1 retain number: %d", [thisIsSubObject retainCount]);
	
	[myarray addObject:thisIsSubObject];
	NSLog(@"2 retain number: %d", [thisIsSubObject retainCount]);
	
	[Object setMySubObject: thisIsSubObject];
	NSLog(@"3 retain number: %d", [thisIsSubObject retainCount]);
	
	[thisIsSubObject release];// here retain number equal 1
	NSLog(@"4 retain number: %d", [thisIsSubObject retainCount]);

	[pool drain]; // why "thisIsSubObject" is released? I didn't sending autorelease message to thisIsSUbObject???
	
	
    return 0;
}
output

2011-04-09 16:13:47.073 kjhnm,[3909:a0f] 1 retain number: 1
2011-04-09 16:13:47.076 kjhnm,[3909:a0f] 2 retain number: 2
2011-04-09 16:13:47.076 kjhnm,[3909:a0f] 3 retain number: 2
2011-04-09 16:13:47.077 kjhnm,[3909:a0f] 4 retain number: 1
2011-04-09 16:13:47.077 kjhnm,[3909:a0f] dealloc called

Why when I send drain message to pool, thisIsSubObject was released even though I didn't apply [thisIsSubObject autoreleased]?
ksiedzulek is offline   0 Reply With Quote
Old Apr 9, 2011, 11:17 AM   #13
Sydde
macrumors 68000
 
Sydde's Avatar
 
Join Date: Aug 2009
Quote:
Originally Posted by ksiedzulek View Post
I think I start to feel it!

...but one more question, this time about autorelease pool.
here is a code (and question below):

Code:
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];	
		
	NSMutableArray *myarray=[NSMutableArray arrayWithCapacity:10];

	[myarray addObject:thisIsSubObject];

	[thisIsSubObject release];// here retain number equal 1

	[pool drain]; // why "thisIsSubObject" is released? I didn't sending autorelease message to thisIsSUbObject???
	
    return 0;
}
output

2011-04-09 16:13:47.073 kjhnm,[3909:a0f] 1 retain number: 1
2011-04-09 16:13:47.076 kjhnm,[3909:a0f] 2 retain number: 2
2011-04-09 16:13:47.076 kjhnm,[3909:a0f] 3 retain number: 2
2011-04-09 16:13:47.077 kjhnm,[3909:a0f] 4 retain number: 1
2011-04-09 16:13:47.077 kjhnm,[3909:a0f] dealloc called

Why when I send drain message to pool, thisIsSubObject was released even though I didn't apply [thisIsSubObject autoreleased]?
the method +arrayWithCapacity: allocates the array, then adds it to the autorelease pool. When you drain the pool, myarray gets released, which cause it to send release to everything it contains.
__________________
You got to be a spirit. You can't be no ghost.
Sydde is online now   0 Reply With Quote
Old Apr 9, 2011, 12:05 PM   #14
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by gnasher729 View Post
You _must_ forget about retainCount. Instead you _must_ read and understand the "Memory Management Programming Guide.".
Link to the guide:
http://developer.apple.com/library/m...emoryMgmt.html
chown33 is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Learning Obj-c feedback arkmannj iPhone/iPad Programming 11 Apr 25, 2014 12:22 AM
Any thoughts on the comma operator (C/C++/Obj-C?) ArtOfWarfare Mac Programming 12 Feb 26, 2013 05:46 AM
C, Obj-C, C++, some questions argh silentownage001 Mac Programming 24 Feb 12, 2013 02:20 AM
What to learn aside Obj C Will0827 iPhone/iPad Programming 8 Sep 27, 2012 04:07 PM
Need help with indexing (Java or Obj-C) iVikD Mac Programming 5 Jul 5, 2012 06:43 PM

Forum Jump

All times are GMT -5. The time now is 08:05 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC