Re: Initializing an Array
Re: Initializing an Array
- Subject: Re: Initializing an Array
- From: Jeff Galyan <email@hidden>
- Date: Tue, 22 Jan 2002 11:57:56 -0700
Here's an example of what I'm talking about:
/****************
* AppCrasher.h
****************/
#import <Foundation/Foundation.h>
@interface AppCrasher : NSObject
{
NSString *myString;
}
- (id)initWithString:(NSString *)aString;
- (void)dealloc;
- (NSString *)methodOne;
- (NSString *)methodTwo;
- (NSString *)methodThree;
- (NSString *)methodFour;
- (NSString *)methodFive;
- (NSString *)methodSix;
@end
/*****************
* AppCrasher.m
*****************/
#import "AppCrasher.h"
@implementation AppCrasher
- (id)initWithString:(NSString *)aString
{
myString = [aString copy];
[myString retain];
return self;
}
- (void)dealloc
{
[myString release];
}
- (NSString *)methodOne
{
// create a char* and send [myString getCString] with it
// do something with the C string
// return a new NSString
}
- (NSString *)methodTwo
{
// same concept as methodOne
}
...
@end
/********************
* SomeClass.h
********************/
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
{
}
- (void)getCrashed:(NSString *)someString;
@end
/**********************
* SomeClass.m
**********************/
#import "SomeClass.h"
#import "AppCrasher.h"
@implementation SomeClass
- (void)getCrashed:(NSString *)someString
{
AppCrasher *myCrasher;
NSString *strOne, *strTwo, *strThree, *strFour, *strFive, *strSix;
myCrasher = [[AppCrasher alloc] initWithString:someString];
strOne = [myCrasher methodOne];
strTwo = [myCrasher methodTwo];
strThree = [myCrasher methodThree];
strFour = [myCrasher methodFour];
strFive = [myCrahser methodFive];
strSix = [myCrasher methodSix];
}
@end
Then in some class, you allocate an instance of SomeClass and call
getCrashed with some string while iterating over a counter. After the third
or fourth call to getCrashed, the app will crash. If you step through in the
debugger (and remember, this is with optimization turned off), you'll see a
new instance of myCrasher get created, then while you step through the calls
to you'll see myString get initialized properly, then somewhere between the
call to methodFour and methodSix (it varies), myString suddenly becomes nil,
even though myCrasher has not been deallocated yet, so therefore, the ivar
myString should not be getting sent a release message.
My application does something very similar to this very rapidly at app
launch.
If I get rid of the ivar myString in AppCrasher and change the methods to
require passing in an NSString pointer when called, it works fine.
--Jeff
On 1/22/02 10:26 AM, "Jeff Galyan" <email@hidden> wrote:
>
My CFLAGS do not include any -O flags, just -g.
>
>
--Jeff
>
>
>
On 1/22/02 5:17 AM, "Marcel Weiher" <email@hidden> wrote:
>
>
>
>
> On Tuesday, January 22, 2002, at 10:58 , Jeff Galyan wrote:
>
>
>
>>
>
>> Also, this code:
>
>>>>> NSArray *myArray = [[NSArray arrayWithObjects:@"Do
>
>>>>> unto",@"others", nil] retain];
>
>>
>
>> Be careful where you put your retain calls. I've got some code I'm
>
>> debugging
>
>> right now where I did exactly like the above, but it turns out the
>
>> message
>
>> is getting sent to a different instance than I expected,
>
>
>
> That should not be the case. Be careful with debugging optimized code!
>
> Although the optmization will yield the same end-result, intermediate
>
> values will have been re-arranged quite signicantly, with variables
>
> disappearing, taking on different values etc.
>
>
>
>> or rather, the
>
>> return type indicated in the docs apparently has no meaning to the
>
>> runtime.
>
>> For example, one would think that because retain returns type id that
>
>> that
>
>> means you can keep that pointer around. Wrong. The runtime is
>
>> deallocating
>
>> all of those pointers I set up like above almost as soon as they're
>
>> returned
>
>> from the receiver (stepping through in the debugger, I saw one of them
>
>> last
>
>> for two statements before it evaporated... "0x0" is never an address one
>
>> likes to see appear in the vars pane).
>
>
>
> This is a very typical sign of debugging optimized code.
>
>
>
>> So, you have to do this:
>
>> NSArray *myArray = [NSArray arrayWithObjects:@"Do unto", @"others",
>
>> nil];
>
>> [myArray retain];
>
>
>
> Thist code has the same effect as the above. However, it may force the
>
> optimizer to actually keep myArray arround in its expected location a
>
> bit longer. Message sends and non-static function calls are opaque to
>
> the optmizer, so you can use them to make variables 'sticky'.
>
>
>
>> Makes me wonder why retain returns anything at all.
>
>
>
> -retain is fine, I am almost 100% certain that this is something else.
>
>
>
> Marcel
>
> --
>
> Marcel Weiher Metaobject Software Technologies
>
> email@hidden www.metaobject.com
>
> Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc.
>
_______________________________________________
>
cocoa-dev mailing list | email@hidden
>
Help/Unsubscribe/Archives:
>
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
>
Do not post admin requests to the list. They will be ignored.