【问题标题】:iOS Memory Management & NSString InitialisationiOS 内存管理和 NSString 初始化
【发布时间】:2011-11-26 07:10:30
【问题描述】:

仍在学习使用 ObjectiveC 和 iOS 进行 iOS 开发,并尝试真正了解内存管理!感谢以下关于 sn-p 的任何建议,例如: 1) Analyzer 说存在潜在的内存泄漏,但无法解决? 2) 我应该在 for 循环中以及附加到时保留分配和初始化 NSStrings 吗?

谢谢

- (NSString *) lookUpCharNameForID: (NSString *) inCharID
{
    debugPrint ("TRACE", [[@"Lookup Char Name for = " stringByAppendingString: inCharID] UTF8String]);


    NSString *tempName = [[NSString alloc] initWithFormat: @""];
    if (![inCharID isEqualToString: @""])
    {
        // Potentially lookup multiple values
        //
        NSString *newName   = [[NSString alloc] initWithFormat: @""];
        NSArray *idList     = [inCharID componentsSeparatedByString: @","];
        for (NSString *nextID in idList)
        {
            NSLog( @"Lookup %i : %@", [idList count], nextID);
            newName = [[NSString alloc] initWithFormat: @"C%@", nextID];

            // Append strings
            if ([tempName isEqualToString: @""])
                tempName = [[NSString alloc] initWithFormat: @"%@", newName];
            else
                tempName = [[NSString alloc] initWithFormat: @"%@+%@", tempName, newName];
        }
        [newName release];
    }

    return [tempName autorelease];
}

【问题讨论】:

    标签: ios memory-leaks nsstring


    【解决方案1】:

    对新项目使用 ARC(自动引用计数)。对于较旧的项目,转换它们可能很容易,如果不是,可以在必要时逐个文件禁用 ARC。

    使用可变字符串、自动释放的便利方法和一些重构:

    - (NSString *) lookUpCharNameForID: (NSString *) inCharID
    {
        NSMutableString *tempName = [NSMutableArray array];
    
        if (inCharID.length)
        {
            NSArray *idList = [inCharID componentsSeparatedByString: @","];
            for (NSString *nextID in idList)
            {
                if (tempName.length == 0)
                    [tempName appendFormat: @"%@C", nextID];
                else
                    [tempName appendFormat: @"+%@C", nextID];
            }
        }
    
        return tempName;
    }
    

    【讨论】:

      【解决方案2】:

      您不需要对allocreleaseautorelease 的任何调用。相反,使用[NSString stringWithFormat:] 创建不属于您的NSString 实例,因此不需要管理。另外,考虑使用NSMutableString 来简化您的代码,例如按照以下(未经测试的)版本:

      - (NSString *) lookUpCharNameForID: (NSString *) inCharID
      {
          NSMutableString *tempName = nil;
      
          if (![inCharID isEqualToString: @""])
          {
              NSArray *idList = [inCharID componentsSeparatedByString: @","];
      
              for (NSString *nextID in idList)
              {
                  [tempName appendString:@"+"]; // Does nothing if tempName is nil.
      
                  if (tempName == nil)
                      tempName = [NSMutableString string];
      
                  [tempName appendFormat:@"C%@", nextID];
              }
          }
      
          return tempName;
      }
      

      【讨论】:

      • 谢谢,这样更整洁了;我确实认为您应该使用 initwithformat 但并不真正理解为什么
      • alloc 的调用应始终与对init... 方法的调用配对。但是,当您调用 alloc 时,您获得了它返回的对象的所有权,并且必须最终通过向对象发送 releaseautorelease 消息来放弃所有权。阅读或至少略读一下 Apple 的内存管理指南以获取更完整的图片真的很有帮助:developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
      【解决方案3】:

      您有 2 个用于 tempName 的 alloc initWithFormat。一个在循环之前,一个在循环内。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-13
        • 1970-01-01
        • 2017-04-12
        • 2012-07-18
        • 2016-10-12
        • 2012-12-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多