0

I've got a singleton (StoreManager) to help me manage my In-App Purchases, and it has a property called productArray, which is set like so:

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    self.productArray = response.products;
}

In my store's view controller, I have this code:

-(void)setupPrices 
{
    if ([[StoreManager sharedStoreManager] productArray]) {
        [productArray objectAtIndex:2]...
}

It was working fine for a while, but now I get SIGABRT: index 2 beyond bounds of empty array, so clearly my if statement has passed as true, even though the method that sets the value hasn't been called yet. I thought this was weird so I tried some code and it seems if I do

NSArray *array;
NSLog (@"%u", array.count);

I get bad access and if I do

NSArray *array;
if (array)
    NSLog(@"Array is not nil");

The statement passes. I'm sure I'm missing something here. How do I check if my array has been set?

nathan
  • 1,348
  • 1
  • 13
  • 31

2 Answers2

2

Here, array may be an uninitialized garbage value:

NSArray *array;

Here, you need to use an NSString, not a c string:

NSLog ("%u", array.count);

But you are along the right path, in that you can test the object for nil, then its count. Many people just write something like if (n < [array count]) ... because in this case, the result of [array count] will be 0 if array is 0.

Just reconsider how you initialize your objects' state (meh, singletons...) and turn up the compiler warnings. It would also help to add some sanity check assertions to verify that your singleton is constructed properly when it is used externally.

justin
  • 101,751
  • 13
  • 172
  • 222
  • Turns out it was array.count causing the problem, changing it to [array count] fixed it. I'm assuming this is because the array hadn't been initialized, but I don't know. Any reason to not use singletons? I have two view controllers that use in-app purchases and using a singleton halved my code. – nathan Oct 27 '11 at 05:43
  • yes, there are a lot of answers to that on this site. jalf's answer here was the first i found that i liked: http://stackoverflow.com/questions/1020312/are-singletons-really-that-bad – justin Oct 27 '11 at 06:04
  • i've also written about it: http://stackoverflow.com/questions/7635008/alternative-to-global-variables-in-app-delegate/7635786#7635786, http://stackoverflow.com/questions/7143162/singleton-in-objective-c/7143523#7143523, http://stackoverflow.com/questions/7219106/how-do-i-debug-singletons-in-objective-c/7219129#7219129, http://stackoverflow.com/questions/4887391/what-is-the-correct-system-design-when-dealing-with-third-party-api/4892417#4892417 – justin Oct 27 '11 at 06:10
  • 1
    @Justin : I'm not quite clear, are you in favour of singletons or not? ;) – jrturton Oct 27 '11 at 07:12
  • @jrturton if you'd like to be convinced, i'll send my programs to you and you can remove the old legacy ones which i have not gotten around to (yet) =) – justin Oct 27 '11 at 07:18
  • @Justin certainly, my daily rates are very reasonable! – jrturton Oct 27 '11 at 07:46
  • @jrhurton i would hope so! there's a loooooot of competition over this task =) – justin Oct 27 '11 at 08:49
1

count is a method of NSArray, not a property.

NSLog(@"%d", [array count]);

Check if the array's count is atleast 3 before you access the object at index 2.

EmptyStack
  • 50,606
  • 20
  • 144
  • 175
  • 1
    +1, I used to hate NullPointerException while working on java, But now it seems nice to have that! Because Objective C is so quite when it's nil. – TeaCupApp Oct 27 '11 at 04:16
  • 1
    Dot syntax and declared properties are orthogonal. –  Oct 27 '11 at 08:33