I have a subclass of NSManagedObject with a few "integer 32" attributes that are really enums. These enums are defined in my model's .h file like this:
typedef enum {
AMOwningCompanyACME,
AMOwningCompanyABC,
AMOwningCompanyOther
} AMOwningCompany;
I need to show a table view that displays the value of each attribute of this custom object, so for each enum I have a method that looks like this to return string values:
-(NSArray*)stringsForAMOwningCompany
{
return [NSArray arrayWithObjects:@"ACME Co.", @"ABC Co.", @"Other", nil];
}
In my table view, I iterate through the attributes of my NSManagedObject
(using NSEntityDescription
's attributesByName
and for each attribute I call a helper method that calls the appropriate "stringsFor" method to return the strings for that particular attribute:
-(NSArray*)getStringsArrayForAttribute:(NSString*)attributeName
{
SEL methodSelector = NSSelectorFromString([self methodNameForAttributeNamed:attributeName]);
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:[[AMProperty class] instanceMethodSignatureForSelector:methodSelector]];
[invocation setSelector:methodSelector];
[invocation setTarget:self.editingPole];
[invocation invoke];
NSArray* returnValue = nil;
[invocation getReturnValue:&returnValue];
return returnValue;
}
My table view's cellForRowAtIndexPath
looks like this:
...
NSString* itemName = self.tableData[indexPath.row];
NSAttributeDescription* desc = itemAttributes[itemName];
NSString* cellIdentifier = [self cellIdentifierForAttribute:desc]; // checks the attribute type and returns a different custom cell identifier accordingly
if ([cellIdentifier isEqualToString:@"enumCell"])
{
// dequeue cell, customize it
UITableViewCell* enumCell = ...
...
NSArray* stringValues = [[NSArray alloc] initWithArray:[self getStringArrayForAttribute:itemName]];
int currentValue = [(NSNumber*)[self.editingPole valueForKey:itemName] intValue];
enumCell.detailTextLabel.text = (NSString*)stringValues[currentValue];
return enumCell;
}
...
For only one of the attributes, I keep getting a crash on the NSInvocation
's return array:
-[__NSArrayI release]: message sent to deallocated instance 0x856a4b0
Using the Zombies Profiler, I see:
I am using ARC. How can I debug this further?
I ran into a very similar problem myself recently and it took me a while to figure out what I was doing wrong. An extra release is being issued here -- because your pointer returnValue
is __strong
(the default), ARC believes that the object is owned via that pointer, but that's not the case.
-[NSInvocation getReturnValue:]
doesn't take ownership of it, and the "assignment" via the pointer's address bypasses the objc_storeStrong()
that ARC would normally use.
The solution is simple: mark the pointer as __unsafe_unretained
. This is the truth; the object is not retained via this pointer (as it would if it were __strong
), and ARC must not release it here.
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