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?
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,
¬RetainedCallbacks);
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.