Found NSZombie in my application ... now what?

I have a subclass of NSManagedObject with several "integer 32" attributes that are actually listed. These listings are defined in my model .h file as follows:

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 listing, 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 repeat the attributes of my NSManagedObject (using NSEntityDescription attributesByName and for each attribute, I call a helper method that calls the corresponding "stringingsFor" method to return the rows for this 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 view of the cellForRowAtIndexPath table is as follows:

 ... 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 just one of the attributes, I receive an error message in the returned NSInvocation array:

 -[__NSArrayI release]: message sent to deallocated instance 0x856a4b0 

Using the Zombies Profiler, I see:

Instruments Screenshot

I am using ARC. How can I debug this further?

+4
source share
1 answer

I recently ran into very similar problems, and it took me a while to figure out what I was doing wrong. An extra release is issued here, because your returnValue pointer is __strong (the default), ARC considers the object to belong to this pointer, but that is not the case.

-[NSInvocation getReturnValue:] does not get ownership of it, and "assignment" bypasses the objc_storeStrong() address, which usually uses ARC, through the address of the pointer.

The solution is simple: mark the pointer as __unsafe_unretained . It's true; the object is not saved through this pointer (as if it were __strong ), and ARC should not release it.

+8
source

Source: https://habr.com/ru/post/1497633/


All Articles