在我的应用程序中找到了一个N​​SZombie ......现在怎么样?

时间:2013-08-18 02:40:45

标签: ios objective-c debugging malloc nsinvocation

我有一个NSManagedObject的子类,有一些“整数32”属性,它们真的是枚举。这些枚举在我的模型的.h文件中定义,如下所示:

typedef enum {
    AMOwningCompanyACME,
    AMOwningCompanyABC,
    AMOwningCompanyOther
} AMOwningCompany;

我需要显示一个表视图,显示该自定义对象的每个属性的值,因此对于每个枚举,我有一个看起来像这样的方法来返回字符串值:

-(NSArray*)stringsForAMOwningCompany
{
    return [NSArray arrayWithObjects:@"ACME Co.", @"ABC Co.", @"Other", nil];
}

在我的表视图中,我遍历NSManagedObject的属性(使用NSEntityDescription的{​​{1}},对于每个属性,我调用一个调用相应“stringsFor”的辅助方法返回该特定属性的字符串的方法:

attributesByName

我的表格视图-(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; } 如下所示:

cellForRowAtIndexPath

对于其中一个属性,我一直在... 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; } ... 的返回数组上崩溃:

NSInvocation

使用Zombies Profiler,我看到:

Instruments Screenshot

我正在使用ARC。我该如何进一步调试?

1 个答案:

答案 0 :(得分:8)

我最近遇到了一个非常类似的问题,我花了一段时间才弄清楚我做错了什么。这里发布了一个额外的版本 - 因为你的指针returnValue__strong(默认值),ARC认为该对象是通过该指针拥有的,但事实并非如此。

-[NSInvocation getReturnValue:]不会取得它的所有权,并且通过指针地址的“赋值”会绕过ARC通常使用的objc_storeStrong()

解决方案很简单:将指针标记为__unsafe_unretained。这是事实;该对象不会通过此指针保留(如果它是__strong),并且ARC不能在此处释放它。