I am converting some code to ARC. The code searches for an element in an NSMutableArray, then finds, removes, and returns that element. The problem is that the element gets deallocated immediately upon "removeObjectAtIndex":
- (UIView *)viewWithTag:(int)tag
{
UIView *view = nil;
for (int i = 0; i < [self count]; i++)
{
UIView *aView = [self objectAtIndex:i];
if (aView.tag == tag)
{
view = aView;
NSLog(@"%@",view); // 1 (view is good)
[self removeObjectAtIndex:i];
break;
}
}
NSLog(@"%@",view); // 2 (view has been deallocated)
return view;
}
When I run it, I get
*** -[UIView respondsToSelector:]: message sent to deallocated instance 0x87882f0
at the second log statement.
Pre-ARC, I was careful to retain the object before calling removeObjectAtIndex:, and then to autorelease it. How do I tell ARC to do the same thing?
Declare the UIView *view
reference with the __autoreleasing
qualifier, like so:
- (UIView *)viewWithTag:(int)tag
{
__autoreleasing UIView *view;
__unsafe_unretained UIView *aView;
for (int i = 0; i < [self count]; i++)
{
aView = [self objectAtIndex:i];
if (aView.tag == tag)
{
view = aView;
//Since you declared "view" as __autoreleasing,
//the pre-ARC equivalent would be:
//view = [[aView retain] autorelease];
[self removeObjectAtIndex:i];
break;
}
}
return view;
}
__autoreleasing
will give you exactly what you want because on assignment the new pointee is retained, autoreleased, and then stored into the lvalue.
See the ARC reference
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With