Re: Initializing an Array
Re: Initializing an Array
- Subject: Re: Initializing an Array
- From: Jeff Galyan <email@hidden>
- Date: Tue, 22 Jan 2002 12:15:52 -0700
I forgot to mention that I'm also seeing this happening with my UI objects
created in Interface Builder. I have some timers that send messages to my
class (which then sends messages to different UI objects, for example an
NSSlider) at various intervals. The ivars are typed like so:
IBOutlet NSSlider *aSlider;
During execution, the timers get set up and added to the run loop. Then,
after a timer has sent a few messages that my class has responded to by
sending [aSlider setIntValue:anInt], aSlider suddenly becomes nil and the
app UI stops responding (even though the NSSlider still shows on the
interface).
--Jeff
On 1/22/02 11:57 AM, "Jeff Galyan" <email@hidden> wrote:
>
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.