目标C:切换内部循环 - 如何避免(潜在的)内存泄漏

时间:2012-05-14 08:22:45

标签: objective-c release switch-statement autorelease alloc

我有一个for循环,在开始时声明了NSObject“value”,然后实际创建了“value”中的switch语句。 “value”则可以是NSNumber,NSDate,NSData,NSString或nil。这是代码:

for (int i = 0; i < self.columnCount; i++) {
  NSObject *value;
  switch (mysql_fields[i].type) {
    case ...
      ...
    case MYSQL_TYPE_LONG:
      value = [[NSNumber alloc] initWithInt:atoi(row[i])];
      /* [value autorelease]; */  // 2)
      break;
    case MYSQL_TYPE_DECIMAL:
      NSString *decimal = [[NSString alloc] initWithCString:(char *)row[i] encoding:NSUTF8StringEncoding];
      value = [[NSDecimalNumber alloc] initWithString:decimal];
      /* [value autorelease]; */  // 2)
      [decimal release];
      break;
    case ...
      ...
  } // end of switch
} end of for
Field *field = [[[Field alloc] initWithRecord:record] autorelease];
/* [value autorelease]; */  // 3)
[field setValue:value forKey:@"value"];
/* [value release]; */  // 4)

现在我不知道如何释放“价值”。这就是我尝试的和相应的Xcode 4“Analyzer”消息:

  1. 没有发布 - &gt; “潜在泄漏”
  2. 在每个case语句中的alloc / init之后的
  3. [value autorelease] - &gt; “对象发送autorelease太多次了”
  4. [值autorelease]直接在最后一次使用之前 - &gt; “对象发送autorelease太多次了”
  5. 最后一次使用后
  6. [价值发布] - &gt; “此时不属于调用者的对象的引用计数的不正确的减少”

2 个答案:

答案 0 :(得分:1)

仅在分配对象的位置添加自动释放,删除其余部分:

value = [[[NSNumber alloc] initWithInt:atoi(row[i])] autorelease];
// ....
value = [[[NSDecimalNumber alloc] initWithString:decimal] autorelease];

答案 1 :(得分:0)

你在for循环中声明value,所以你必须在开关之后释放它但是在for循环中。

for (int i = 0; i < self.columnCount; i++)
{
    NSObject *value;
    switch (mysql_fields[i].type)
    {
        case ...
            ...
        case MYSQL_TYPE_LONG:
            value = [[NSNumber alloc] initWithInt:atoi(row[i])];
            break;
        case MYSQL_TYPE_DECIMAL:
            NSString *decimal = [[NSString alloc] initWithCString:(char *)row[i] encoding:NSUTF8StringEncoding];
            value = [[NSDecimalNumber alloc] initWithString:decimal];
            [decimal release];
            break;
        case ...
            ...
    }
    Field *field = [[[Field alloc] initWithRecord:record] autorelease];
    [field setValue:value forKey:@"value"];
    [value release];
}