0

What I am doing is

    //ClassB.h
    @property (strong, nonatomic) NSString  *name;

and

 //ClassA.h
 @interface ClassA : NSObject
 +(ClassA*)methodA:(NSData*)data;
 -(id)initWithData:(NSData*)data;

    @property (nonatomic, strong) NSMutableArray *arr; 
    @property (nonatomic, strong) RXMLElement    *rxmlRoot; 

    @end

    //ClassA.m
    @implementation ClassA
    @synthesize arr;
    @synthesize rxmlRoot;

    +(ClassA*)methodA:(NSData*)data {
        return [[ClassA alloc] initWithData:data];
    }

    -(id)initWithData:(NSData*)data {
        self = [super init];
        if (self) {
            arr      = [NSMutableArray array];
            rxmlRoot = [RXMLElement elementFromXMLData:data];

             /*****edit : just been added to make codes clear*****/  
            NSString    *node   =   @"players.player";
            [rxmlRoot iterate:node with:^(RXMLElement *e){
                 ClassB   *classB  =   [[[ClassB alloc] init] autorelease];
                 [classB setName:       [e attribute:@"name"]];

                 // adding ClassB into arr
                 [arr addObject:classB];
            }];

        }
        return self;
    }
    @end

So now I am having ClassA object whose arr contains ClassB

Question : later on, when I try to access an particular property of ClassB like

((ClassB*)[classA.arr objectAtIndex:0]).name

and I am getting EXC_BAD_ACCESS at above line..

Please advice me on this issue and how to correct the error. Any comments are welcomed here

Thanks

0

3 Answers 3

1

This line

[arr addObject:ClassB]

makes no sense. Is your intention to put an instance of ClassB into that array, or the class itself (i.e. [ClassB class])? Presumably you must intend to put an instance of ClassB in there, otherwise trying to access its properties later on (e.g. firstName) would make no sense. Also, does your ClassB even have a firstName property, because the piece of ClassB's interface that you show us only mentions a name property.

Update:

Since you are using manual memory management, you need to retain the objects (arr, rxmlRoot) you create in your initializer using convenience constructors, which return autoreleased objects. For example, the code should be

arr = [[NSMutableArray array] retain];
Sign up to request clarification or add additional context in comments.

6 Comments

So do you actually have a firstName property in ClassB or not?
i am so sorry about that. firstName should be name.
I am using manual... If I just on ARC and get rid of release or autorelease, it works properly....
Or rather than retain it yourself, as UIAdam suggests, use the property you have created. (I'd change 'strong' to 'retain' for clarity - they do the same thing when ARC is off - but 'strong' is associated with ARC code so it can confuse). So [self setArr: [NSMutableArray array]]; Then the setter you have synthesized does the memory management for you. But the point is good. The EXC_BAD_ACCESS is arising because you're sending something to an object that has been released.
@MatthewElton although you're right that it will work, I believe popular convention is to avoid using properties in initializers in case they have side effects that are invalid for a not-completely-initialized object.
|
0

Post your ClassB.m . Are you making the @synthesize name?

Also make the Alloc for arr.

This line is so wrong:

((ClassB*)[classA.arr objectAtIndex:0]).firstName

Your string is called name , not firstName. It should be :

((ClassB*)[classA.arr objectAtIndex:0]).name

3 Comments

I just edited. firstName should be name after all. Sorry about that. I did create an arr by using arr = [NSMutableArray array];
try making an alloc. Something like
arr = [[NSMutablearray alloc] initWithCapacity:0];
0

The code in the question has changed substantially, so my previous answer now makes no sense and I have removed it. Given revised code, the first thing to do is to log what's going on.

NSLog(@"classA: %@", classA);
NSLog(@"classA.arr: %@", classA.arr);

((ClassB*)[classA.arr objectAtIndex:0]).name

If it blows up on the first log statement, things are really bad. But then at least you know that classA is pointing to something rotten and you can work back from there.

You can achieve the same thing in the debugger, by setting a break point ahead of the line and inspecting. Given that you are getting an EXC_BAD_ACCESS one of the pointers is pointing to a dodgy object, e.g. one that has been released. It looks as if you are using ARC (because you have strong in your property), which should help manage the memory - but then again, you have an autorelease in there, so maybe not.

1 Comment

Other stackoverflow users appreciate it if you post code that actually compiles when you first ask the question. Otherwise, folk are going to pick up on the wrong issues. Of course, it's good to post very short bits of code too, which is why folk will appreciate it if you extract as much code as you can but still have the issue and only then post your question and code. (Experience shows that when you do this, about 50% of the time, you fix the issue before you need to post here at all.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.