开发者

NSArray runtime array

I have got I have got two methods both in different classes. One is class method and other is instance method. i am calling class method from instance method. When instance method finishes it gives runtime error "EXC_BAD_ACCESS".

#import "xmlObject.h"
#import "textmeAppDelegate.h"
@implementation Class1 
    - (void)method1 {
               textmeAppDelegate *del = (textmeAppDelegate *)[[UIApplication sharedApplication] delegate];

               NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]];
               UIColor *color = [UIColor colorWithRed:[[bgColor objectAtIndex:3] floatValue] green:[[bgColor objectAtIndex:2] floatValue] blue:[[bgColor objectAtIndex:1] floatValue] alpha:[[bgColor objectAtIndex:0] floatValue]];
               CGContextSetFillColor(context, CGColorGetComponents([color CGColor]));
               CGContextFillRect(context, rect);
               [bgColor release];

        }
    @end

@implementation xmlObject 
        + (NSArray *) fetchImmediateChildrenValues:(NSMutableDictionary *) node {
         NSMutableDictionary *tmp = [[node objectForKey:@"childr开发者_StackOverflow社区en"] retain];
         NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]];
         keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
         NSMutableArray *pushArr = [[[NSMutableArray alloc] init] autorelease];
         NSString *val = [[NSString alloc] init];
         for(NSString *str in keys) {
           val = (NSString *)[[tmp objectForKey:str] objectForKey:@"innertext"];
          [pushArr addObject:val];
         }
         [val release];
         [keys release];

         return  [NSArray arrayWithArray:pushArr];
        }

@end

What is wrong with the code? Also app is crashing for this line of code application is crashing if i include this line

 NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]];

If I remove it application runs smoothly.


I have several comments on your code. One of them is the immediate cause of your crash, but you need to fix at least one other issue too. The short answer is that you over release val and keys.

NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]];

You don't need to create a new array here, you can simply write the following:

NSArray *bgColor = [xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]];

if you do, you don't need the [bgColor release] further down.

NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]];
keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

These two lines leak the first NSArray, you alloc it but you overwrite it straight away with the sorted version. In fact, you can simply write:

keys = [[tmp allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

Note that you do not own keys so you can get rid of the [keys release] line further down.

NSString *val = [[NSString alloc] init];
for(NSString *str in keys) {
   val = (NSString *)[[tmp objectForKey:str] objectForKey:@"innertext"];
   [pushArr addObject:val];
}
[val release];

This is the source of your immediate problem. You first alloc a new string. Then you immediately overwrite it on each iteration of your loop. So the allocated NSString leaks. You do not own the val returned by [[tmp objectForKey:str] objectForKey:@"innertext"]; on each iteration, so the release ov val after the loop should not be there.

On a side note, objectForKey: returns an id - the cast to NSString* is redundant. Most people leave it out.

         [keys release];

Going back to the bit above where I told you that you were leaking your alloc'd keys? Well the new version of keys you overwrote it with you don't own. Therefore you must not release keys here.

return  [NSArray arrayWithArray:pushArr];

This is fine. My preference would be for:

return [[pushArray copy] autorelease];

but it is just a matter of style. You could also just return pushArray, but pushArray is mutable and the caller may rely on the return value being immutable.


Test your code with NSZombieEnabled set... It should give you enough informations to fix your problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜