可变参数函数 - 调用 [obj release] 时的 EXC_BAD_ACCESS;

发布于 2024-09-02 05:23:18 字数 650 浏览 8 评论 0原文

我有以下方法:

(void)makeString:(NSString *)str1,... {

 va_list 字符串;

   NSString *innerText = [[NSString alloc] init];
   NSString *tmpStr = [[NSString alloc] init];

   如果(str1){

       va_start(字符串, str1); 

       while (tmpStr = va_arg(字符串, id)) { 
            innerText = [innerText stringByAppendingString:tmpStr];
       }

       label.text = [str1 stringByAppendingString:innerText];
   }

   [tmpStr 释放];

}

我最终会阅读《Objective C Memory Management》,我确信我会找到这个问题的答案 - 可能与指针和复制有关 - ,但是对于现在,任何人都可以解释为什么我添加 [innerText release];作为该函数的最后一行,我在运行时收到 EXC_BAD_ACCESS 错误?

I have the following method:

(void)makeString:(NSString *)str1,... {

   va_list strings;

   NSString *innerText = [[NSString alloc] init];
   NSString *tmpStr = [[NSString alloc] init];

   if (str1) {

       va_start(strings, str1); 

       while (tmpStr = va_arg(strings, id)) { 
            innerText = [innerText stringByAppendingString:tmpStr];
       }

       label.text = [str1 stringByAppendingString:innerText];
   }

   [tmpStr release];

}

I will eventually get to Objective C Memory Management reading, where I'm sure I will find the answer to this - probably related to pointers and copying - , but for now, can anyone explain why if I add [innerText release]; as the last line of this function, i get an EXC_BAD_ACCESS error at runtime?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦旅人picnic 2024-09-09 05:23:18

首先,您的代码是错误的。
据我所知,您只是连接字符串以将结果分配给 label.text
我假设 label 是一个 ivar,因此 label.text = ... 是合法的。然后应该执行以下操作:

- (void)makeString: (NSString *)str1, ...
{
   if (str1) {
       NSString *tmpStr;

       va_list strings;
       va_start(strings, str1);
       while (tmpStr = va_arg(strings, id)) {
            str1 = [str1 stringByAppendingString: tmpStr];
       }

       label.text = str1;
   }
}

一些注意事项:

  • 您不应该释放任何输入参数,除非您的方法是要释放某些内容。
  • 正如第一个答案所述,您不应释放 stringByAppendingString: 的结果,除非
    你之前已经保留过它。

[更新]

我更改了答案,因为它包含错误。 label.text = str1 当然应该保留str1(如果它想保留的话)。特别是调用代码不应该保留str1,除非它想保留它自己。

First, your code is erroneous.
As far as I can see you are only concatenating the strings to assign the result to label.text.
I assume that label is an ivar, so label.text = … ist legal. Then the following should do it:

- (void)makeString: (NSString *)str1, ...
{
   if (str1) {
       NSString *tmpStr;

       va_list strings;
       va_start(strings, str1);
       while (tmpStr = va_arg(strings, id)) {
            str1 = [str1 stringByAppendingString: tmpStr];
       }

       label.text = str1;
   }
}

Some notes:

  • You should not release any input parameter unless your method is about releasing something.
  • As the first answer stated, you should not release the result of stringByAppendingString: unless
    you have retained it before.

[Update]

I changed the answer because it contained an error. label.text = str1 should retain str1 of course (if it wants to keep it). Especially the calling code should not retain str1 unless it wants to keep it for itself.

冷…雨湿花 2024-09-09 05:23:18

stringByAppendingString 返回一个自动释放的字符串,该字符串将替换您的原始分配。所以不需要你的释放。但是上面的两个分配会泄漏内存。

您可能也应该使用 [NSString initWithCString:va_arg(strings, id)] 来分配 tmpStr 。

stringByAppendingString returns an autoreleased string, which is replacing your original assignment. So your release is not needed. But you are leaking memory with the two allocs above.

You should probably use [NSString initWithCString:va_arg(strings, id)] to assign the tmpStr too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文