1

Using the following code I am always getting category.subCategories count to be 0 using the Xcode debugger

Category *category = [[Category alloc] init];
category.title = @"Pubs & Bars";
category.icon = @"cat_pubs&bars";
category.subCategories == [[NSMutableArray alloc] init];

Category *subCategory = [[Category alloc] init];
subCategory.title = @"Test Sub Category 1";

[category.subCategories addObject:subCategory];

The object defined using the following code:

@interface Category : NSObject {
    NSInteger *categoryId;
    NSMutableString *title;
    NSString *icon;
    NSMutableArray *subCategories;
}

@property(assign,nonatomic,readonly) NSInteger *categoryId;
@property(nonatomic,copy) NSMutableString *title;
@property(nonatomic,copy) NSString *icon;
@property(nonatomic,retain) NSMutableArray *subCategories;

@end
3
  • 1
    Your code will leak memory - you need to release array assigned to subCategories and subCategory itself as you increase their retain count. Commented Jan 26, 2010 at 12:23
  • thanks but this is just a prototype the actual code will read data from SQLite Commented Jan 26, 2010 at 13:54
  • Because the data will be coming from a webservice and there will be quite a lot of it, which I will not always want in memory Commented Jan 27, 2010 at 13:33

1 Answer 1

7

In the following line, category.subCategories == [[NSMutableArray alloc] init];, you have a double equal and that check if it's true. So subCategories is still nil here, that's why you have a count of 0.

Use category.subCategories = [[NSMutableArray alloc] init]; instead.

Personally, I would use a custom getter to lazily create an NSMutableArray. In Category.m :

- (NSMutableArray*) subCategories {
   if (subCategories == nil) {
      subCategories = [[NSMutableArray alloc] init];
   }
   return subCategories;
}

That way, you just need to use subCategories as it is already existent, since it will be created on demand. That way, you also no more have a leak.

Sign up to request clarification or add additional context in comments.

3 Comments

Right about the problem, but I personally disagree about the custom getter. Initializers are for initialization code. No need to fling it to the four corners of the earth and create more additional code on top of it.
I personally think it's easier. Lazy creation is one of the design pattern of Cocoa. It also can save memory (this argument is irrelevant in this case, but can be a huge win sometimes). And that's my personal taste, create the subCategories in the init method is also right. However, it's easier to think about it as 'I need it now, why wouldn't I create it' than 'I will probably need it later, create it.' (for me at least).
I don't think Lazy Creation really is a Cocoa design pattern. However, on the iPHone it is probably good practice since you don't have that much memory to work with. Being conservative with memory usage is always a good idea on smaller devices.

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.