Relying on the (copy) attribute to copy NSMutableDictionary causes crash - objective-c

The following program relies on the copy
attribute to copy a NSMutableDictionary.
The copy is apparently ok, but, if I try
to add a new element to the copy, the program crashes.
Is it some kind of bug?
PS. If it matters it's NON ARC
#import <Foundation/Foundation.h>
#interface Dog: NSObject
#property (copy) NSMutableDictionary *dict;
#end
#implementation Dog
#synthesize dict;
- (id) init
{
if ( (self = [super init]) ) {
dict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void) print {
for (id key in dict) {
printf("%s --> %s\n", [key UTF8String], [dict[key] UTF8String] );
}
}
#end
//------------------------------------------------------
int main() {
Dog *dog1 = [[Dog alloc] init];
Dog *dog2 = [[Dog alloc] init];
dog1.dict[#"color"] = #"black";
dog2.dict = dog1.dict;
[dog2 print];
// the print shows that dog2.dict is indeed a copy of dog1.dict
// lldb shows that it is a shallow copy, which I guess is ok
// since values are immutable.
// ... so far so good.
dog1.dict[#"tail"] = #"long"; // This goes smoothly
//
// But...
dog2.dict[#"tail"] = #"long";
// here program crashes with the following message
//
// -[__NSDictionaryI setObject:forKeyedSubscript:]: unrecognized selector sent to instance 0x100108ee0
//*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI setObject:forKeyedSubscript:]: unrecognized selector sent to instance 0x100108ee0'
return(0);
}
EDIT:
If I replace the line
dog2.dict = dog1.dict;
with
[dog2.dict addEntriesFromDictionary: dog1.dict];
then it works. There is no crash.
So, OK, this is the correct way of doing it.
But my point is: don't I deserve at least a warning
from the compiler?

You've broken some rules here, which is why it's going badly for you. As a rule, you should not return or accept NSMutableDictionary as a property. There are exceptions (and you have to code around that), but generally you should not. To code this correctly, you need to separate your interface from your implementation.
The correct interface is:
#interface Dog: NSObject
#property (copy) NSDictionary *dict;
#end
This object promises to accept and return NSDictionary, and it promises that the accepted and returned NSDictionaries will be independent copies, so the caller doesn't need to worry about mutability issues. We then need to implement those promises:
#implementation Dog {
NSMutableDictionary *mutableDict;
}
- (id) init
{
if ( (self = [super init]) ) {
mutableDict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void) print {
for (id key in mutableDict) {
printf("%s --> %s\n", [key UTF8String], [mutableDict[key] UTF8String] );
}
}
- (NSDictionary *)dict {
return [mutableDict copy]; // Add an -autorelease if this is MRC
}
- (void)setDict: (NSDictionary *)newValue {
// I'm going to pretend this is ARC; for MRC, code this in your style.
mutableDict = [newValue mutableCopy];
}
#end
On the other hand, if you really do want to share state with an NSMutableDictionary, you should not copy it, you should retain it to make clear the semantics.
#interface Dog: NSObject
#property (retain) NSMutableDictionary *dict;
#end
And this makes it (hopefully) clear to the caller that this is shared state and should be treated as such, and the caller should make copies if they so desire. But you generally should avoid this. And if you do go this way, I would call the property mutableDict or something like that to make it clear that this is unusual. For an example, see -[NSAttributedString mutableString].
There's not really a "mutable, but independent copy" semantic in ObjC property annotations, and I wouldn't create one unless you have a very strong need (generally performance related). I would generally just return an immutable copy and let the caller make their own mutable copy.
One more side note: Sometimes Cocoa implements "returns an immutable copy" as "just return the mutable one, cast to an immutable type." This improves performance by avoiding the copy, at the cost of sometimes the data changing behind your back. As an example, look at the docs for -[NSView subviews]. In my opinion you should avoid this pattern unless it is critical for performance (and even then, I'd make a special method like -subviewsBackingStore or something silly like that to make it clear "this is weird."

copy attribute creates an NSDictionary instance, not NSMutableDictionary, that's why it's crashing.
First, change the property to retain from copy:
#property (retain) NSMutableDictionary* duct;
Then you can do the following:
Dog *dog2 = [[Dog alloc] init];
dog2.dict = [dog1.dict mutableCopy];

Related

How can I make a deep copy in Objective-C?

I'm learning ios development and I'm confused with deep copying in Objective-C.
For example,I have three class below. Now I want to deep copy ClassA, can anybody teach me to finish the copy method?
A:
#interface ClassA : NSObject <NSCopying>
#property (nonatomic, assign) int aInt;
#property (nonatomic, retain) ClassB *bClass;
#end
B:
#interface ClassB : NSObject <NSCopying>
#property (nonatomic, assign) int bInt;
#property (nonatomic, retain) ClassC *cClass;
#end
C:
#interface ClassC : NSObject <NSCopying>
#property (nonatomic, assign) int cInt;
#property (nonatomic, copy) NSString *str;
#end
Following the explanation at http://www.techotopia.com/index.php/Copying_Objects_in_Objective-C
"This can be achieved by writing the object and its constituent elements to an archive and then reading back into the new object."
#implementation ClassA
- (id)copyWithZone:(NSZone*)zone{
NSData *buffer;
buffer = [NSKeyedArchiver archivedDataWithRootObject:self];
ClassA *copy = [NSKeyedUnarchiver unarchiveObjectWithData: buffer];
return copy;
}
#end
You should add the copyWithZone: method in each class you want to be copiable.
NB: I wrote this by hand, watch out for typos.
-(id) copyWithZone:(NSZone *) zone
{
ClassA *object = [super copyWithZone:zone];
object.aInt = self.aInt;
object.bClass = [self.bClass copyWithZone:zone];
return object;
}
-(id) copyWithZone:(NSZone *) zone
{
ClassB *object = [super copyWithZone:zone];
object.bInt = self.bInt;
object.cClass = [self.cClass copyWithZone:zone];
return object;
}
-(id) copyWithZone:(NSZone *) zone
{
ClassC *object = [super copyWithZone:zone];
object.cInt = self.cInt;
object.str = [self.str copy];
return object;
}
Objective-C on iOS doesn’t offer any direct language or library construct to switch between a shallow and a deep copy. Each class defines what it means to “get its copy”:
#implementation ClassA
- (id) copyWithZone: (NSZone*) zone
{
ClassA *copy = [super copyWithZone:zone];
[copy setBClass:bClass]; // this would be a shallow copy
[copy setBClass:[bClass copy]]; // this would be a deep copy
return copy;
}
#end
Of course you would have to do the same decision in ClassB and ClassC. If I am not mistaken, the usual semantics for a copy in Objective-C is to return a shallow copy. See also this question about copying arrays for more discussion of the topic.
I had custom classes with long lists of properties, so I iterated over them:
#interface MyClass : NSObject <NSCopying>
#import <objc/runtime.h>
-(id) copyWithZone: (NSZone *) zone {
MyClass *myCopy = [[MyClass alloc] init];
//deepCopy
unsigned int numOfProperties;
objc_property_t *properties = class_copyPropertyList([self class], &numOfProperties);
for (int i = 0; i < numOfProperties; i++) {
objc_property_t property = properties[i];
NSString *propertyName = [[NSString alloc]initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
[adressCopy setValue:[[self valueForKey:propertyName] copy] forKey:propertyName];
}
return myCopy;
}
All customClassProperties will need to implement this as well.
This could be of some help. The link shows how to do the deep copy using NSKeyedArchiver
http://iphonecodecenter.wordpress.com/2013/08/26/difference-between-shallow-copy-and-deep-copy/
Objective-C's copy and copyWithZone specifications are bogus and dangerous and should not be used.
--!-- At least not when used with ARC (Automatic Reference Counting) (2016-08-23) --!--
The code will lead to writing out of the bounds of memory / buffer overflows.
Instead I present a method to safely copy objects initAsShallowCopy and deepCopy.
See my test results in code below:
#import <Foundation/Foundation.h>
#interface ClassA : NSObject
{
#public
NSMutableString* A_Name;
NSInteger A_NSInteger;
long int A_int;
float A_float;
}
-(id)init;
-(id)copyWithZone:(NSZone *) zone; // DON'T USE copy OR copyWithZone, unless you ignore Apple's guidelines and always make shallow copies in line with the correct example code here for initAsShallowCopy (but you return a copy instead of being a copy)
-(id)initAsShallowCopy:(ClassA *)original; // Correct way to make a shallow copy
-(void)deepCopy; // Correct way to make a deep copy (Call initAsShallowCopy first)
#end
#interface ClassB : ClassA
{
#public
NSMutableString* B_Name;
NSInteger B_NSInteger;
long int B_int;
float B_float;
}
-(id)init;
-(id)copyWithZone:(NSZone *) zone; // DON'T USE copy OR copyWithZone, unless you ignore Apple's guidelines and always make shallow copies in line with the correct example code here for initAsShallowCopy (but you return a copy instead of being a copy)
-(id)initAsShallowCopy:(ClassB *)original; // Correct way to make a shallow copy
-(void)deepCopy; // Correct way to make a deep copy (Call initAsShallowCopy first)
-(void)print;
#end
#interface ClassCWithoutCopy : NSObject
{
#public
NSMutableString* C_Name;
NSInteger C_NSInteger;
long int C_int;
float C_float;
}
-(id)init;
-(void)print;
#end
#implementation ClassA
-(id)init
{
if ( self = [super init] ) { // initialize NSObject
//A_Name = [[NSMutableString alloc] init];
//[A_Name setString:#"I am inited to A"];
A_Name = [NSMutableString stringWithString:#"I am inited to A"];
A_NSInteger = 1;
A_int = 1;
A_float = 1.0;
return self;
}
return nil;
}
/*
FROM https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/#//apple_ref/occ/instm/NSObject/copy
-- NSObject Class Reference --
- (id)copy
Discussion
This is a convenience method for classes that adopt the NSCopying protocol. An exception is raised if there is
no implementation for copyWithZone:.
NSObject does not itself support the NSCopying protocol. Subclasses must support the protocol and
implement the copyWithZone: method. A subclass version of the copyWithZone: method should send the message to super first,
to incorporate its implementation, unless the subclass descends directly from NSObject.
+ copyWithZone:
Discussion
This method exists so class objects can be used in situations where you need an object that conforms to the NSCopying protocol.
For example, this method lets you use a class object as a key to an NSDictionary object.
You should not override this method.
CONCLUSION
copy says we should incorporate the implementation of copyWithZone, while copyWithZone says we should not override it.. So what is it?
Looking at copyWithZone, we see that it is a class method (+), meaning it has not access to its instantiated members.
So maybe they mean, we should not override the class method (+), but we should implement its instance method -copyWithZone:
!!In any case we should not implement copy, because it is just made for convenience by Apple!!
FROM: https://developer.apple.com/library/tvos/documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/index.html
-- NSCopying --
Your options for implementing this protocol are as follows:
1) Implement NSCopying using alloc and init... in classes that don’t inherit copyWithZone:.
2) Implement NSCopying by invoking the superclass’s copyWithZone: when NSCopying behavior is inherited.
If the superclass implementation might use the NSCopyObject function, make explicit assignments to
pointer instance variables for retained objects.
3) Implement NSCopying by retaining the original instead of creating a new copy when the class and its contents are immutable.
CONCLUSION:
From 1) NSObject does not implement copyWithZone so any class that you make that should support copying should call [[Class alloc] init].
From 2) Any subclass of a copyable object should call [super copyWithZone:zone], but NOT [[Class alloc] init] !!!!!!
*/
-(id) copyWithZone:(NSZone *) zone
{
ClassA *CopiedObject = [[ClassA alloc] init];
if(CopiedObject){
CopiedObject->A_Name = [A_Name copy];
CopiedObject->A_NSInteger = A_NSInteger;
CopiedObject->A_int = A_int;
CopiedObject->A_float = A_float;
return CopiedObject;
}
return nil;
}
-(id)initAsShallowCopy:(ClassA *)original // Correct way to make a shallow copy
{
/* Why this has to be done like this:
It is very annoying to assign every variable explicitely.
However this has to be done, in order for ARC (Automatic Reference Counting) (2016-08-23) to work.
The compiler needs to be aware of any reference made to an object or reference cleared to an object in order to keep track of the
reference counts.
The danger is that when you add a variable to you class later on, you must not forget to update your initAsShallowCopy function and
possibly your DeepCopy function.
It would be much nicer if you could just do:
*self = *original;
But that gives compiler error:
/DeepCopyTest/main.m:135:9: Cannot assign to class object ('ClassA' invalid)
So therefore there is also no raw memory copy between objects,
so we are stuck with writing out each member variable explicitely.
*/
if ( self = [super init] ) { // initialize NSObject
A_Name = original->A_Name;
A_NSInteger = original->A_NSInteger;
A_int = original->A_int;
A_float = original->A_float;
return self;
}
return nil;
}
-(void)deepCopy; // Correct way to make a deep copy (Call initAsShallowCopy first)
{
/* Luckily now, we only have to duplicate the objects that require a deep copy.
So we don't have to write out all the floats, ints and NSIntegers, etcetera. Thus only the pointers (*) to objects.
*/
A_Name = [A_Name copy];
}
#end
#implementation ClassB
-(id)init
{
if ( self = [super init] ) { // initialize ClassA
B_Name = [NSMutableString stringWithString:#"I am inited to B"];
B_NSInteger = 2;
B_int = 2;
B_float = 2.0;
return self;
}
return nil;
}
-(id) copyWithZone:(NSZone *) zone
{
//ClassA *CopiedObject = [[ClassA alloc] init]; We are not a direct descendant from NSObject, so don't call alloc-init
// instead call the super copyWithZone
ClassB *CopiedObject = [super copyWithZone:zone]; /* Using ARC (Automatic Reference Counting) 2016-08-23:
THIS IS A MASSIVE BUFFER OVERFLOW/WRITING OUT OF BOUNDS RISK:
Since super now allocates the object, it will now only allocate an object of size ClassA
and effectively allocate too little memory for the ClassB. Unless memory allocation is upgraded to work with magic for
Objective-C, DON'T USE copy or copyWithZone!!!!
*/
if(CopiedObject){
CopiedObject->B_Name = [B_Name copy];
CopiedObject->B_NSInteger = B_NSInteger;
CopiedObject->B_int = B_int;
CopiedObject->B_float = B_float;
return CopiedObject;
}
return nil;
}
-(id)initAsShallowCopy:(ClassB *)original // Correct way to make a shallow copy
{
if ( self = [super initAsShallowCopy:original] ) { // initialize ClassA
B_Name = original->B_Name;
B_NSInteger = original->B_NSInteger;
B_int = original->B_int;
B_float = original->B_float;
return self;
}
return nil;
}
-(void)deepCopy; // Correct way to make a deep copy (Call initAsShallowCopy first)
{
/* Luckily now, we only have to duplicate the objects that require a deep copy.
So we don't have to write out all the floats, ints and NSIntegers, etcetera. Thus only the pointers (*) to objects.
*/
[super deepCopy];
B_Name = [B_Name copy];
}
-(void)print
{
NSLog(#"A_Name=\"%#\", A_NSInteger=%ld,A_int=%ld,A_float=%f",A_Name,A_NSInteger,A_int,A_float);
NSLog(#"B_Name=\"%#\", B_NSInteger=%ld,B_int=%ld,B_float=%f",B_Name,B_NSInteger,B_int,B_float);
}
#end
#implementation ClassCWithoutCopy
-(id)init
{
if ( self = [super init] ) { // initialize NSObject
C_Name = [NSMutableString stringWithString:#"I am inited to C"];
C_NSInteger = 3;
C_int = 3;
C_float = 3.0;
return self;
}
return nil;
}
-(void)print
{
NSLog(#"C_Name=\"%#\", C_NSInteger=%ld,C_int=%ld,C_float=%f",C_Name,C_NSInteger,C_int,C_float);
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
ClassB *OriginalB;
ClassB *CopiedB;
#define USE_CORRECT_DEEP_COPY_AND_SHALLOW_COPY 1
#define USE_CLASSC_WITHOUT_COPY_TEST 0
#if(USE_CLASSC_WITHOUT_COPY_TEST)
ClassCWithoutCopy *OriginalC;
ClassCWithoutCopy *CopiedC;
OriginalC = [[ClassCWithoutCopy alloc] init];
CopiedC = [OriginalC copy]; /* Thread 1: signal SIGABRT: libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ClassCWithoutCopy copyWithZone:]: unrecognized selector sent to instance 0x100100450' */
//CopiedC = [ClassCWithoutCopy copyWithZone:nil]; /* DeepCopyTest/main.m:283:33: 'copyWithZone:' is unavailable: not available in automatic reference counting mode
*/
NSLog(#"OriginalC print:1");
[OriginalC print];
NSLog(#"CopiedC print:1");
[CopiedC print];
[OriginalC->C_Name appendString:#" and Appended as the original"];
OriginalC->C_NSInteger = 30;
OriginalC->C_int = 30;
OriginalC->C_float = 30.0;
NSLog(#"OriginalC print:2");
[OriginalC print];
NSLog(#"CopiedC print:2");
[CopiedC print];
#endif
#if(USE_CORRECT_DEEP_COPY_AND_SHALLOW_COPY)
OriginalB = [[ClassB alloc] init];
CopiedB = [[ClassB alloc] initAsShallowCopy:OriginalB];
NSLog(#"OriginalB print:1");
[OriginalB print];
NSLog(#"CopiedB print:1");
[CopiedB print];
[OriginalB->A_Name appendString:#" and Appended as the original"];
OriginalB->A_NSInteger = 10;
OriginalB->A_int = 10;
OriginalB->A_float = 10.0;
[OriginalB->B_Name appendString:#" and Appended as the original"];
OriginalB->B_NSInteger = 20;
OriginalB->B_int = 20;
OriginalB->B_float = 20.0;
NSLog(#"OriginalB print:2");
[OriginalB print];
NSLog(#"CopiedB print:2");
[CopiedB print];
// This works as expected: The values of OriginalB and CopiedB differ, but the shallow copied strings are the same.
// Now make a deep copy of CopiedB
[CopiedB deepCopy];
[OriginalB->A_Name appendString:#" and Appended twice as the original"];
OriginalB->A_NSInteger = 100;
OriginalB->A_int = 100;
OriginalB->A_float = 100.0;
[OriginalB->B_Name appendString:#" and Appended twice as the original"];
OriginalB->B_NSInteger = 200;
OriginalB->B_int = 200;
OriginalB->B_float = 200.0;
NSLog(#"OriginalB print:3");
[OriginalB print];
NSLog(#"CopiedB print:3");
[CopiedB print];
// This works as expected: The values of OriginalB and CopiedB differ and als the deep copied strings are different.
#else
OriginalB = [[ClassB alloc] init];
CopiedB = [OriginalB copy]; // Undefined behaviour. You will write unallocated memory
NSLog(#"OriginalB print:1");
[OriginalB print];
NSLog(#"CopiedB print:1");
/*[CopiedB print]; / * Thread 1: signal SIGABRT: libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ClassA print]: unrecognized selector sent to instance 0x10010ad60' */
NSLog(#"A_Name=\"%#\", A_NSInteger=%ld,A_int=%ld,A_float=%f",CopiedB->A_Name,CopiedB->A_NSInteger,CopiedB->A_int,CopiedB->A_float);
NSLog(#"B_Name=\"%#\", B_NSInteger=%ld,B_int=%ld,B_float=%f",CopiedB->B_Name,CopiedB->B_NSInteger,CopiedB->B_int,CopiedB->B_float); // Undefined behaviour. You will read unallocated memory
[OriginalB->A_Name appendString:#" and Appended as the original"];
OriginalB->A_NSInteger = 10;
OriginalB->A_int = 10;
OriginalB->A_float = 10.0;
[OriginalB->B_Name appendString:#" and Appended as the original"];
OriginalB->B_NSInteger = 20;
OriginalB->B_int = 20;
OriginalB->B_float = 20.0;
// This at least works: Changing Original, does not alter the values of Copy.
NSLog(#"OriginalB print:2");
[OriginalB print];
NSLog(#"CopiedB print:2");
NSLog(#"A_Name=\"%#\", A_NSInteger=%ld,A_int=%ld,A_float=%f",CopiedB->A_Name,CopiedB->A_NSInteger,CopiedB->A_int,CopiedB->A_float);
//NSLog(#"B_Name=\"%#\", B_NSInteger=%ld,B_int=%ld,B_float=%f",CopiedB->B_Name,CopiedB->B_NSInteger,CopiedB->B_int,CopiedB->B_float); // Undefined behaviour. You will read unallocated memory
/*[CopiedB->A_Name appendString:#" and Appended as the copy"]; / * Thread 1: signal SIGABRT: libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:' */
CopiedB->A_NSInteger = 100;
CopiedB->A_int = 100;
CopiedB->A_float = 100.0;
/*[CopiedB->B_Name appendString:#" and Appended as the copy"]; / * Thread 1: signal SIGABRT: libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'*/
CopiedB->B_NSInteger = 200; // Undefined behaviour. You will write unallocated memory
CopiedB->B_int = 200; // Undefined behaviour. You will write unallocated memory
CopiedB->B_float = 200.0; // Undefined behaviour. You will write unallocated memory
/* Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
DeepCopyTest(2376,0x7fff7edda310) malloc: *** error for object 0x10010ad98: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug */
NSLog(#"OriginalB print after modification of CopiedB:");
[OriginalB print];
NSLog(#"CopiedB print after modification of CopiedB:");
/*[CopiedB print];; / * Thread 1: signal SIGABRT: libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ClassA print]: unrecognized selector sent to instance 0x10010ad60' */
#endif
}
return 0;
}
PS-1: FROM:
https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectCopying.html
-- Object copying --
A deep copy duplicates the objects referenced while a shallow copy duplicates only the references to those objects. So if object A is shallow-copied to object B, object B refers to the same instance variable (or property) that object A refers to. Deep-copying objects is preferred to shallow-copying, especially with value objects.
NOTE:
This is unclear formulation, especially with the accompanied illustration, which suggests a wrong explanation.
This formulation makes it appear that two references to the same object count as a shallow copy. This is not true. It isn't a copy at all.
The clear formulation would be that:
-A shallow copy of an object has all the values and references copied from its parent, but is itself a unique object in memory.
-A deep copy of an object has all the values copied from its parent and is itself a unique object in memory, but all the references now reference to -deep themselves - copies of the original references objects.
Although the exact implementation of deep copying might not 100% give deep copies.
Objects that point to external references (suchs as a hardware item or graphics driver can't be duplicated, but only increase the reference count)
Some deep copying has no functional sense. An object might reference its window it is in, but it makes no sense to duplicate the window.
An object might also reference data that is considered immutable, so it would not be efficient to duplicate that.
PS-2: You could have give me the hint of ctrl-K before I tried to format all my code manually.
PS-3: Apple-Z (undo) undoes all my formatting instead of the last one and I can't redo it.

debugging objective c memory leak with xCode Leaks

I'm doing my first steps in finding memory leaks in xCode 4.5 and using the Leaks instrument. I found a couple of issues and seemed to fix them, but this one eludes me.
Here is the code:
RUBEImageInfo* imgInfo = [[[RUBEImageInfo alloc] init] autorelease];
NSString *nm = [NSString stringWithUTF8String:img->name.c_str()];
imgInfo->name = nm;
[imgInfo->name retain]; // I'm using it outside of this method
Leaks reports a leak in the second line, with the percentage next to the "i" at %100.
So I tried two things:
One, I marked nm with autohrleas like this:
NSString *nm = [[NSString stringWithUTF8String:img->name.c_str()] autorelease];
Two, I also tried calling release on nm after it's assignment to imgInfo->name so the code looks like this:
imgInfo->name = nm;
[imgInfo->name retain];
[nm release];
But in both cases the app crashes with BAD_ACCESS when I run it, and call [imgInfo->name UTF8String].
What am I missing?
EDIT following Rob's answer:
This is the RUBEImageInfo class:
#import "cocos2d.h"
#interface RUBEImageInfo : NSObject {
#public CCSprite* sprite; // the image
#public NSString* name; // the file the image was loaded from
#public class b2Body* body; // the body this image is attached to (can be NULL)
#public float scale; // a scale of 1 means the image is 1 physics unit high
#public float angle; // 'local angle' - relative to the angle of the body
#public CGPoint center; // 'local center' - relative to the position of the body
#public float opacity; // 0 - 1
#public bool flip; // horizontal flip
#public int colorTint[4]; // 0 - 255 RGBA values
}
#end
And the .m:
#import "RUBEImageInfo.h"
#implementation RUBEImageInfo
// Nothing much to see here. Just make sure the body starts as NULL.
-(id)init
{
if( (self=[super init])) {
body = NULL;
}
return self;
}
-(void) dealloc {
[name release];
[super dealloc];
}
#end
A couple of reactions:
Instruments identified where the leaked object was allocated, but in this case, this code might not be the source of the leak. You should:
ensure you release the name in the dealloc method of RUBEImageInfo; and
also, if you're setting name a second time, make sure you release the previous name object before you set it to a new object.
Your life will be much easier if you use declared properties rather than dereferencing class instance variables. For example, if name was declared as:
#property (nonatomic, copy) NSString *name; // you could use `retain`, too, but `copy` is safer when dealing with strings
Then you would set the name property as so:
RUBEImageInfo* imgInfo = [[[RUBEImageInfo alloc] init] autorelease];
NSString *nm = [NSString stringWithUTF8String:img->name.c_str()];
imgInfo.name = nm;
// this is no longer needed as the `name` setter will take care of memory semantics
// [imgInfo->name retain]; // I'm using it outside of this method
By using the setter accessor method (i.e. the "dot syntax" of imgInfo.name), it will take care of a lot of routine memory semantics of releasing any previous object that name may have referenced, and it will do the necessary copy or retain. Obviously, the RUBEImageInfo method dealloc still needs to release name, but at least it simplifies the memory semantics of the name property of RUBEImageInfo objects.
Since you are using manual reference counting, I'd encourage you to investigate the "static analyzer" (invoked by selecting "Analyze" from Xcode's "Product" menu). The Leaks tool in Instruments will tell you what leaked, but it doesn't tell you where the leak happened; it has no way of knowing; it can only show you where the leaked object was allocated and you'll have to hunt down the logic error yourself. The static analyzer can sometimes point out errors that lead to leaks, but more importantly, show you where the leak was caused, rather than just where the leaked object was originally instantiated. You should have a clean bill of health from the static analyzer before you even bother running Instruments.
Looking at your code sample, if you're not going to use declared properties (not sure why you wouldn't, as it makes life easier, but to each his own), I'd suggest making sure you initialize all of your objects in init and release all of them in dealloc:
#implementation RUBEImageInfo
-(id)init
{
if ((self=[super init])) {
body = NULL;
name = nil;
sprite = nil;
// I might initialize other class instance variables here, too, but that's up to you
}
return self;
}
-(void) dealloc {
[name release];
// shouldn't you release `body` and `sprite`, too?
[super dealloc];
}
#end
Then your code that sets the name instance variable would make sure to release the previous object before setting the new object. Thus the initial instantiation might look like:
RUBEImageInfo* imgInfo = [[[RUBEImageInfo alloc] init] autorelease];
NSString *nm = [NSString stringWithUTF8String:img->name.c_str()];
imgInfo->name = [nm retain]; // retain the new object
But if you update it later, you should:
NSString *nm = [NSString stringWithUTF8String:someNewImg->name.c_str()];
[imageInfo->name release]; // release the old one
imgInfo->name = [nm retain]; // retain the new object

is it allowed to call [obj copy] in ObjC with ARC?

There's one thing I don't understand regarding ARC: how should we now treat local variables that were created using [... copy]? If I make a property with (copy) flag, ARC will handle this automatically, but as far as I know there's no __copy flag for variables.
I've tested this with such code:
#interface Foo : NSString
#end
#implementation Foo
- (void) dealloc {
NSLog(#"%p deallocated", self);
}
- (NSUInteger) length {
return 1;
}
- (unichar) characterAtIndex: (NSUInteger) i {
return 'x';
}
#end
- (void) foo {
Foo *f = [[Foo alloc] init];
NSLog(#"%p", f);
Foo *f2 = [f copy];
NSLog(#"%p", f2);
}
What I get is:
0x102406530
0x102015f10
0x102406530 deallocated
I never get "0x102015f10 deallocated", which would suggest the copied variable doesn't get released. It doesn't even get autoreleased, because when I made another method [Foo foo] that returned an autoreleased object, I did get a "deallocated" message a moment later.
So is there any way I can cause it to be released without converting it to a property?
Ok, my bad - ARC does actually handle copied objects properly. I got wrong results because of using NSString for the test, because I wanted to use a class that already implemented copying instead of implementing it explicitly; when I repeated the test on a class inheriting from NSObject and implementing copyWithZone: by returning [[Foo alloc] init], I got two "deallocated" messages. Thanks to #Paul.s for pointing that out.

NSArray of weak references (__unsafe_unretained) to objects under ARC

I need to store weak references to objects in an NSArray, in order to prevent retain cycles. I'm not sure of the proper syntax to use. Is this the correct way?
Foo* foo1 = [[Foo alloc] init];
Foo* foo2 = [[Foo alloc] init];
__unsafe_unretained Foo* weakFoo1 = foo1;
__unsafe_unretained Foo* weakFoo2 = foo2;
NSArray* someArray = [NSArray arrayWithObjects:weakFoo1, weakFoo2, nil];
Note that I need to support iOS 4.x, thus the __unsafe_unretained instead of __weak.
EDIT (2015-02-18):
For those wanting to use true __weak pointers (not __unsafe_unretained), please check out this question instead: Collections of zeroing weak references under ARC
As Jason said, you can't make NSArray store weak references. The easiest way to implement Emile's suggestion of wrapping an object inside another object that stores a weak reference to it is the following:
NSValue *value = [NSValue valueWithNonretainedObject:myObj];
[array addObject:value];
Another option: a category that makes NSMutableArray optionally store weak references.
Note that these are "unsafe unretained" references, not self-zeroing weak references. If the array is still around after the objects are deallocated, you'll have a bunch of junk pointers.
The solutions to use a NSValue helper or to create a collection (array, set, dict) object and disable its Retain/Release callbacks are both not 100% failsafe solutions with regard to using ARC.
As various comments to these suggestions point out, such object references will not work like true weak refs:
A "proper" weak property, as supported by ARC, has two behaviors:
Doesn't hold a strong ref to the target object. That means that if the object has no strong references pointing to it, the object will be deallocated.
If the ref'd object is deallocated, the weak reference will become nil.
Now, while the above solutions will comply with behavior #1, they do not exhibit #2.
To get behavior #2 as well, you have to declare your own helper class. It has just one weak property for holding your reference. You then add this helper object to the collection.
Oh, and one more thing: iOS6 and OSX 10.8 supposedly offer a better solution:
[NSHashTable weakObjectsHashTable]
[NSPointerArray weakObjectsPointerArray]
[NSPointerArray pointerArrayWithOptions:]
These should give you containers that hold weak references (but note matt's comments below).
An example (updated 2 Feb 2022)
#import <Foundation/Foundation.h>
static BOOL didDealloc = NO;
#interface TestClass : NSObject
#end
#implementation TestClass
-(void)dealloc {
didDealloc = YES;
}
#end
int main(int argc, const char * argv[]) {
NSPointerArray *pa = [NSPointerArray weakObjectsPointerArray];
#autoreleasepool {
TestClass *obj = TestClass.new;
[pa addPointer:(__bridge void * _Nullable)(obj)]; // stores obj as a weak ref
assert([pa pointerAtIndex:0] != nil);
assert(!didDealloc);
} // at this point the TestClass obj will be deallocated
assert(didDealloc);
assert([pa pointerAtIndex:0] == nil); // verify that the weak ref is null now
return 0;
}
If you run this you'll find that after adding the TestClass object to the pointer array pa, then releasing that object again, the pointer (which is internally a weak object ref) is now set to null as desired.
However, note that calling [pa compact] at the end will not remove the nil pointer as I'd have expected.
I am new to objective-C, after 20 years of writing c++.
In my view, objective-C is excellent at loosely-coupled messaging, but horrible for data management.
Imagine how happy I was to discover that xcode 4.3 supports objective-c++!
So now I rename all my .m files to .mm (compiles as objective-c++) and use c++ standard containers for data management.
Thus the "array of weak pointers" problem becomes a std::vector of __weak object pointers:
#include <vector>
#interface Thing : NSObject
#end
// declare my vector
std::vector<__weak Thing*> myThings;
// store a weak reference in it
Thing* t = [Thing new];
myThings.push_back(t);
// ... some time later ...
for(auto weak : myThings) {
Thing* strong = weak; // safely lock the weak pointer
if (strong) {
// use the locked pointer
}
}
Which is equivalent to the c++ idiom:
std::vector< std::weak_ptr<CppThing> > myCppThings;
std::shared_ptr<CppThing> p = std::make_shared<CppThing>();
myCppThings.push_back(p);
// ... some time later ...
for(auto weak : myCppThings) {
auto strong = weak.lock(); // safety is enforced in c++, you can't dereference a weak_ptr
if (strong) {
// use the locked pointer
}
}
Proof of concept (in the light of Tommy's concerns about vector reallocation):
main.mm:
#include <vector>
#import <Foundation/Foundation.h>
#interface Thing : NSObject
#end
#implementation Thing
#end
extern void foo(Thing*);
int main()
{
// declare my vector
std::vector<__weak Thing*> myThings;
// store a weak reference in it while causing reallocations
Thing* t = [[Thing alloc]init];
for (int i = 0 ; i < 100000 ; ++i) {
myThings.push_back(t);
}
// ... some time later ...
foo(myThings[5000]);
t = nullptr;
foo(myThings[5000]);
}
void foo(Thing*p)
{
NSLog(#"%#", [p className]);
}
example log output:
2016-09-21 18:11:13.150 foo2[42745:5048189] Thing
2016-09-21 18:11:13.152 foo2[42745:5048189] (null)
If you do not require a specific order you could use NSMapTable with special key/value options
NSPointerFunctionsWeakMemory
Uses weak read and write barriers appropriate for ARC or GC. Using NSPointerFunctionsWeakMemory object references will turn to NULL on last release.
I believe the best solution for this is to use NSHashTable or NSMapTable. the Key or/and the Value can be weak. You can read more about it here: http://nshipster.com/nshashtable-and-nsmaptable/
To add weak self reference to NSMutableArray, create a custom class with a weak property as given below.
NSMutableArray *array = [NSMutableArray new];
Step 1: create a custom class
#interface DelegateRef : NSObject
#property(nonatomic, weak)id delegateWeakReference;
#end
Step 2: create a method to add self as weak reference to NSMutableArray. But here we add the DelegateRef object
-(void)addWeakRef:(id)ref
{
DelegateRef *delRef = [DelegateRef new];
[delRef setDelegateWeakReference:ref]
[array addObject:delRef];
}
Step 3: later on, if the property delegateWeakReference == nil, the object can be removed from the array
The property will be nil, and the references will be deallocated at proper time independent of this array references
The simplest solution:
NSMutableArray *array = (__bridge_transfer NSMutableArray *)CFArrayCreateMutable(nil, 0, nil);
NSMutableDictionary *dictionary = (__bridge_transfer NSMutableDictionary *)CFDictionaryCreateMutable(nil, 0, nil, nil);
NSMutableSet *set = (__bridge_transfer NSMutableSet *)CFSetCreateMutable(nil, 0, nil);
Note: And this works on iOS 4.x too.
No, that's not correct. Those aren't actually weak references. You can't really store weak references in an array right now. You need to have a mutable array and remove the references when you're done with them or remove the whole array when you're done with it, or roll your own data structure that supports it.
Hopefully this is something that they'll address in the near future (a weak version of NSArray).
I've just faced with same problem and found that my before-ARC solution works after converting with ARC as designed.
// function allocates mutable set which doesn't retain references.
NSMutableSet* AllocNotRetainedMutableSet() {
CFMutableSetRef setRef = NULL;
CFSetCallBacks notRetainedCallbacks = kCFTypeSetCallBacks;
notRetainedCallbacks.retain = NULL;
notRetainedCallbacks.release = NULL;
setRef = CFSetCreateMutable(kCFAllocatorDefault,
0,
&notRetainedCallbacks);
return (__bridge NSMutableSet *)setRef;
}
// test object for debug deallocation
#interface TestObj : NSObject
#end
#implementation TestObj
- (id)init {
self = [super init];
NSLog(#"%# constructed", self);
return self;
}
- (void)dealloc {
NSLog(#"%# deallocated", self);
}
#end
#interface MainViewController () {
NSMutableSet *weakedSet;
NSMutableSet *usualSet;
}
#end
#implementation MainViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
weakedSet = AllocNotRetainedMutableSet();
usualSet = [NSMutableSet new];
}
return self;
}
- (IBAction)addObject:(id)sender {
TestObj *obj = [TestObj new];
[weakedSet addObject:obj]; // store unsafe unretained ref
[usualSet addObject:obj]; // store strong ref
NSLog(#"%# addet to set", obj);
obj = nil;
if ([usualSet count] == 3) {
[usualSet removeAllObjects]; // deallocate all objects and get old fashioned crash, as it was required.
[weakedSet enumerateObjectsUsingBlock:^(TestObj *invalidObj, BOOL *stop) {
NSLog(#"%# must crash here", invalidObj);
}];
}
}
#end
Output:
2013-06-30 00:59:10.266 not_retained_collection_test[28997:907]
constructed 2013-06-30 00:59:10.267
not_retained_collection_test[28997:907] addet to
set 2013-06-30 00:59:10.581 not_retained_collection_test[28997:907]
constructed 2013-06-30 00:59:10.582
not_retained_collection_test[28997:907] addet to
set 2013-06-30 00:59:10.881 not_retained_collection_test[28997:907]
constructed 2013-06-30 00:59:10.882
not_retained_collection_test[28997:907] addet to
set 2013-06-30 00:59:10.883 not_retained_collection_test[28997:907]
deallocated 2013-06-30 00:59:10.883
not_retained_collection_test[28997:907]
deallocated 2013-06-30 00:59:10.884
not_retained_collection_test[28997:907]
deallocated 2013-06-30 00:59:10.885
not_retained_collection_test[28997:907] * -[TestObj
respondsToSelector:]: message sent to deallocated instance 0x1f03c8c0
Checked with iOS versions 4.3, 5.1, 6.2.
Hope it will be useful to somebody.
If you need zeroing weak references, see this answer for code you can use for a wrapper class.
Other answers to that question suggest a block-based wrapper, and ways to automatically remove zeroed elements from the collection.
If you use a lot this comportment it's indicated to your own NSMutableArray class (subclass of NSMutableArray) which doesn't increase the retain count.
You should have something like this:
-(void)addObject:(NSObject *)object {
[self.collection addObject:[NSValue valueWithNonretainedObject:object]];
}
-(NSObject*) getObject:(NSUInteger)index {
NSValue *value = [self.collection objectAtIndex:index];
if (value.nonretainedObjectValue != nil) {
return value.nonretainedObjectValue;
}
//it's nice to clean the array if the referenced object was deallocated
[self.collection removeObjectAtIndex:index];
return nil;
}
I think an elegant solution is what Mr. Erik Ralston propose on his Github repository
https://gist.github.com/eralston/8010285
this are the essential steps:
create a category for NSArray and NSMutableArray
in the implementation create a convenience class with a weak property. Your category will assign the objects to this weak property.
.h
#import <Foundation/Foundation.h>
#interface NSArray(WeakArray)
- (__weak id)weakObjectForIndex:(NSUInteger)index;
-(id<NSFastEnumeration>)weakObjectsEnumerator;
#end
#interface NSMutableArray (FRSWeakArray)
-(void)addWeakObject:(id)object;
-(void)removeWeakObject:(id)object;
-(void)cleanWeakObjects;
#end
.m
#import "NSArray+WeakArray.h"
#interface WAArrayWeakPointer : NSObject
#property (nonatomic, weak) NSObject *object;
#end
#implementation WAArrayWeakPointer
#end
#implementation NSArray (WeakArray)
-(__weak id)weakObjectForIndex:(NSUInteger)index
{
WAArrayWeakPointer *ptr = [self objectAtIndex:index];
return ptr.object;
}
-(WAArrayWeakPointer *)weakPointerForObject:(id)object
{
for (WAArrayWeakPointer *ptr in self) {
if(ptr) {
if(ptr.object == object) {
return ptr;
}
}
}
return nil;
}
-(id<NSFastEnumeration>)weakObjectsEnumerator
{
NSMutableArray *enumerator = [[NSMutableArray alloc] init];
for (WAArrayWeakPointer *ptr in self) {
if(ptr && ptr.object) {
[enumerator addObject:ptr.object];
}
}
return enumerator;
}
#end
#implementation NSMutableArray (FRSWeakArray)
-(void)addWeakObject:(id)object
{
if(!object)
return;
WAArrayWeakPointer *ptr = [[WAArrayWeakPointer alloc] init];
ptr.object = object;
[self addObject:ptr];
[self cleanWeakObjects];
}
-(void)removeWeakObject:(id)object
{
if(!object)
return;
WAArrayWeakPointer *ptr = [self weakPointerForObject:object];
if(ptr) {
[self removeObject:ptr];
[self cleanWeakObjects];
}
}
-(void)cleanWeakObjects
{
NSMutableArray *toBeRemoved = [[NSMutableArray alloc] init];
for (WAArrayWeakPointer *ptr in self) {
if(ptr && !ptr.object) {
[toBeRemoved addObject:ptr];
}
}
for(WAArrayWeakPointer *ptr in toBeRemoved) {
[self removeObject:ptr];
}
}
#end

How do I make and use a Queue in Objective-C?

I want to use a queue data structure in my Objective-C program. In C++ I'd use the STL queue. What is the equivalent data structure in Objective-C? How do I push/pop items?
Ben's version is a stack instead of a queue, so i tweaked it a bit:
NSMutableArray+QueueAdditions.h
#interface NSMutableArray (QueueAdditions)
- (id) dequeue;
- (void) enqueue:(id)obj;
#end
NSMutableArray+QueueAdditions.m
#implementation NSMutableArray (QueueAdditions)
// Queues are first-in-first-out, so we remove objects from the head
- (id) dequeue {
// if ([self count] == 0) return nil; // to avoid raising exception (Quinn)
id headObject = [self objectAtIndex:0];
if (headObject != nil) {
[[headObject retain] autorelease]; // so it isn't dealloc'ed on remove
[self removeObjectAtIndex:0];
}
return headObject;
}
// Add to the tail of the queue (no one likes it when people cut in line!)
- (void) enqueue:(id)anObject {
[self addObject:anObject];
//this method automatically adds to the end of the array
}
#end
Just import the .h file wherever you want to use your new methods, and call them like you would any other NSMutableArray methods.
I wouldn't say that using NSMutableArray is necessarily the best solution, particularly if you're adding methods with categories, due to the fragility they can cause if method names collide. For a quick-n-dirty queue, I'd use the methods to add and remove at the end of a mutable array. However, if you plan to reuse the queue, or if you want your code to be more readable and self-evident, a dedicated queue class is probably what you want.
Cocoa doesn't have one built in, but there are other options, and you don't have to write one from scratch either. For a true queue that only adds and removes from the ends, a circular buffer array is an extremely fast implementation. Check out CHDataStructures.framework, a library/framework in Objective-C that I've been working on. It has a variety of implementations of queues, as well as stacks, deques, sorted sets, etc. For your purposes, CHCircularBufferQueue is significantly faster (i.e. provable with benchmarks) and more readable (admittedly subjective) than using an NSMutableArray.
One big advantage of using a native Objective-C class instead of a C++ STL class is that it integrates seamlessly with Cocoa code, and works much better with encode/decode (serialization). It also works perfectly with garbage collection and fast enumeration (both present in 10.5+, but only the latter on iPhone) and you don't have to worry about what is an Objective-C object and what is a C++ object.
Lastly, although NSMutableArray is better than a standard C array when adding and removing from either end, it's also not the fastest solution for a queue. For most applications it is satisfactory, but if you need speed, a circular buffer (or in some cases a linked list optimized to keep cache lines hot) can easily trounce an NSMutableArray.
As far as I know, Objective-C does not provide a Queue data structure. Your best bet is to create an NSMutableArray, and then use [array lastObject], [array removeLastObject] to fetch the item, and [array insertObject:o atIndex:0]...
If you're doing this a lot, you might want to create an Objective-C category to extend the functionality of the NSMutableArray class. Categories allow you to dynamically add functions to existing classes (even the ones you don't have the source for) - you could make a queue one like this:
(NOTE: This code is actually for a stack, not a queue. See comments below)
#interface NSMutableArray (QueueAdditions)
- (id)pop;
- (void)push:(id)obj;
#end
#implementation NSMutableArray (QueueAdditions)
- (id)pop
{
// nil if [self count] == 0
id lastObject = [[[self lastObject] retain] autorelease];
if (lastObject)
[self removeLastObject];
return lastObject;
}
- (void)push:(id)obj
{
[self addObject: obj];
}
#end
There's no real queue collections class, but NSMutableArray can be used for effectively the same thing. You can define a category to add pop/push methods as a convenience if you want.
Yes, use NSMutableArray. NSMutableArray is actually implemented as 2-3 tree; you typically need not concern yourself with the performance characteristics of adding or removing objects from NSMutableArray at arbitrary indices.
re:Wolfcow -- Here is a corrected implementation of Wolfcow's dequeue method
- (id)dequeue {
if ([self count] == 0) {
return nil;
}
id queueObject = [[[self objectAtIndex:0] retain] autorelease];
[self removeObjectAtIndex:0];
return queueObject;
}
The solutions that use a category on NSMutableArray are not true queues, because NSMutableArray exposes operations that are a superset of queues. For example, you should not be allowed to remove an item from the middle of a queue (as those category solutions still let you do). It is best to encapsulate functionality, a major principle of object oriented design.
StdQueue.h
#import <Foundation/Foundation.h>
#interface StdQueue : NSObject
#property(nonatomic, readonly) BOOL empty;
#property(nonatomic, readonly) NSUInteger size;
#property(nonatomic, readonly) id front;
#property(nonatomic, readonly) id back;
- (void)enqueue:(id)object;
- (id)dequeue;
#end
StdQueue.m
#import "StdQueue.h"
#interface StdQueue ()
#property(nonatomic, strong) NSMutableArray* storage;
#end
#implementation StdQueue
#pragma mark NSObject
- (id)init
{
if (self = [super init]) {
_storage = [NSMutableArray array];
}
return self;
}
#pragma mark StdQueue
- (BOOL)empty
{
return self.storage.count == 0;
}
- (NSUInteger)size
{
return self.storage.count;
}
- (id)front
{
return self.storage.firstObject;
}
- (id)back
{
return self.storage.lastObject;
}
- (void)enqueue:(id)object
{
[self.storage addObject:object];
}
- (id)dequeue
{
id firstObject = nil;
if (!self.empty) {
firstObject = self.storage.firstObject;
[self.storage removeObjectAtIndex:0];
}
return firstObject;
}
#end
this is my implementation, hope it helps.
Is kind of minimalistic, so you must keep the track of the head by saving the new head at pop and discarding the old head
#interface Queue : NSObject {
id _data;
Queue *tail;
}
-(id) initWithData:(id) data;
-(id) getData;
-(Queue*) pop;
-(void) push:(id) data;
#end
#import "Queue.h"
#implementation Queue
-(id) initWithData:(id) data {
if (self=[super init]) {
_data = data;
[_data retain];
}
return self;
}
-(id) getData {
return _data;
}
-(Queue*) pop {
return tail;
}
-(void) push:(id) data{
if (tail) {
[tail push:data];
} else {
tail = [[Queue alloc]initWithData:data];
}
}
-(void) dealloc {
if (_data) {
[_data release];
}
[super release];
}
#end
Is there some particular reason you cannot just use the STL queue? Objective C++ is a superset of C++ (just use .mm as the extension instead of .m to use Objective C++ instead of Objective C). Then you can use the STL or any other C++ code.
One issue of using the STL queue/vector/list etc with Objective C objects is that they do not typically support retain/release/autorelease memory management. This is easily worked around with a C++ Smart Pointer container class which retains its Objective C object when constructed and releases it when destroyed. Depending on what you are putting in the STL queue this is often not necessary.
Use NSMutableArray.