1

I'm stuck on such code:

static NSMutableSet* test_set;

-(void)foo1
{
  test_set=[NSMutableSet setWithObject:[NSNumber numberWithInt:1]];
  NSLog(@"count:%d",[test_set count]);
}


-(void)foo2
{
  NSLog(@"pointer:%p",test_set);
  NSLog(@"count:%d",[test_set count]); // here I get EXC_BAD_ACCESS
}

I calling foo2 only after foo1. My debug out is like:

count:1
pointer:0x262790
Program received signal:  “EXC_BAD_ACCESS”.

What's wrong? __ Intresting note: it fails only when foo2 is calling in schedule.__ Sorry, I missed details. Both works perfect. Thank you all

2 Answers2

0

You’re not taking ownership of the object being assigned to test_set, which means that it might be deallocated before -foo2 is sent. In general, if you need an object to survive after the execution of a method then you should take ownership of it — for example, via +alloc or -retain:

-(void)foo1
{
  test_set=[[NSMutableSet alloc] initWithObjects:[NSNumber numberWithInt:1], nil];
  NSLog(@"count:%d",[test_set count]);
}

or

-(void)foo1
{
  test_set=[[NSMutableSet setWithObject:[NSNumber numberWithInt:1]] retain];
  NSLog(@"count:%d",[test_set count]);
}

The rules of taking and relinquishing ownership of objects are discussed in the Memory Management Programming Guide.

  • I supposed that it deallocating after foo1. So I used alloc but getting: `-[__NSPlaceholderSet setWithObject:]: unrecognized selector sent to instance 0x228560`retain works perfect. Thank you. My bad about forgetting about memory management – MorskoyZmey Jun 15 '11 at 13:13
  • @Morskoy That’s because `+setWithObject:` is a class method, so you can’t send it to the instance returned by `+alloc`. That’s the reason why I’ve used `-initWithObjects:` in the first example, the one that uses `+alloc`. –  Jun 15 '11 at 13:15
  • @Morskoy Alternatively, you can use the second example — it’s very similar to your original code, with an extra `-retain`. –  Jun 15 '11 at 13:16
  • @Morskoy Just one further note: if you send `-foo1` more than once, you need to relinquish ownership (release) the previous mutable set stored in that variable. Bear that in mind. –  Jun 15 '11 at 13:23
  • I understand. I just thinked, that +setWithObject works like new method in C++, and it returns pointer. how pointer can be auto released?! )) only smart pointer I guess. – MorskoyZmey Jun 15 '11 at 13:47
  • @Morskoy It’s similar to smart pointers. When a method returns an object that’s not owned by the caller, the object may be deallocated eventually. That’s the case of `+setWithObject:`, and the case of methods that return autoreleased objects. That page linked in my answer describes how memory management works. –  Jun 15 '11 at 13:50
0

You haven't retained test_set. The set returned by setWithObject: will be autoreleased. If you add

[test_set retain];

after getting the set back from setWithObject: in foo1(), and add

[test_set release];

to the end of foo2(), it should work.

You should probably read the Cocoa Memory Management Programming Guide.

Adrian B
  • 418
  • 3
  • 7
  • Bavarious's answer is a bit clearer, but I'll leave this here because of the link to the Memory Management guide. – Adrian B Jun 15 '11 at 13:08