【问题标题】:objective c: passing a char argument to function crashes the app目标 c:将 char 参数传递给函数会使应用程序崩溃
【发布时间】:2011-02-16 12:38:20
【问题描述】:

我编写了一个名为 SomeValues 的单例,我在其中初始化了一个 foo NSMutableArray。然后我尝试编写一个函数 SetBFSV 来从不同的控制视图设置这个数组的值。

@interface SomeValues : NSObject {
NSMutableArray *foo;}
+ (SomeValues *) sharedInstance;

@implementation

...

- (void) SetBFSV:(char)lbl ToVal:(long)BFSvl{
NSNumber *ValueBFSvl = [NSNumber numberWithLong:BFSvl];
NSString *Strlbl = [[NSString alloc] stringWithFormat:@"%s",lbl];
[foo setValue:ValueBFSvl forKey:Strlbl];
}

我知道 setValue 需要一个 NS 对象作为值和键,但我不能将我的函数声明为

(void) SetBFSV:(NSString)lbl ToVal:(NSNumber)BFSvl

因为它没有编译并出现错误:“不能使用对象作为方法的参数”。

我在一个 ControlView 中编写了这段代码:

SomeValues *myBFSV = [SomeValues sharedInstance];
const unsigned char *Bar = (unsigned char *)[@"Label1" UTF8String];
NSLog(@"The string %s", Bar);
[myBFSV SetBFSV:Bar ToVal:2.5];

编译时我在最后一行收到警告:

警告:传递 'SetBFSV:ToVal:' 的参数 1 从指针生成整数而不进行强制转换

哪个整数?我越来越愚蠢地四处寻找它。运行时,我从 NSLog 中打印出来,但随后程序显然会因以下错误而崩溃:

'NSInvalidArgumentException',原因:'-[NSPlaceholderString stringWithFormat:]:无法识别的选择器发送到实例 0x4e03280'

很明显,我向 stringWithFormat 传递了一些错误,但我不明白是什么。

感谢您的帮助。祝你有美好的一天!

/卢卡

【问题讨论】:

    标签: iphone objective-c nsstring singleton char


    【解决方案1】:

    您的代码可能存在的问题(除非您的代码中有拼写错误):

    1. - (void) SetBFSV:(char)lbl ToVal:(long)BFSvl 函数需要 char 作为它的第一个参数,但你传递给它一个 char* - 你的第一个警告可能来自这里
    2. stringWithFormat 是一个类方法,所以你的代码应该是:

      NSString *Strlbl = [[NSString alloc] initWithFormat:@"%s",lbl];
      [foo setValue:ValueBFSvl forKey:Strlbl]
      

      NSString *Strlbl = [NSString stringWithFormat:@"%s",lbl];
      [foo setValue:ValueBFSvl forKey:Strlbl]
      

      因为您尝试使用 -stringWithFormat 而不是 +stringWithFormat,所以您会崩溃

    3. 如果将 char 传递给函数,则正确的格式说明符将是 %c,而不是 %s

    4. 如果使用 alloc/init 创建 Strlbl 变量,则可能必须释放它,否则它会泄漏(但如果使用 +stringWithFormat:),则不能释放它

    【讨论】:

      【解决方案2】:

      首先,您不能将对象用作参数:

      (void) SetBFSV:(NSString)lbl ToVal:(NSNumber)BFSvl
      

      您需要使用星号将它们作为指针传递。

      (void) SetBFSV:(NSString*)lbl ToVal:(NSNumber*)BFSvl
      

      此外,如果您需要将它们作为 (char)(long) 传递您的代码:

      SomeValues *myBFSV = [SomeValues sharedInstance];
      const unsigned char *Bar = (unsigned char *)[@"Label1" UTF8String];
      NSLog(@"The string %s", Bar);
      [myBFSV SetBFSV:Bar ToVal:2.5];  // in either case, this is a long.  why are you passing a double here?
      

      *Bar 作为指针传递。您应该真正阅读指针和对象。如果您需要将它们传递为(const char*)(long),请这样做:

      - (void) SetBFSV:(const char*)lbl ToVal:(long)BFSvl{
      NSNumber *ValueBFSvl = [NSNumber numberWithLong:BFSvl];
      NSString *Strlbl = [NSString stringWithUTF8String: lbl]; // your old code had a memory leak here.  you need to either create an autorelease object, or release it after adding to `foo`
      [foo setValue:ValueBFSvl forKey:Strlbl];
      }
      

      我的建议是执行以下操作:

      - (void) SetBFSV:(NSString*)key ToVal:(long)val{
          NSNumber *value = [NSNumber numberWithLong:val];
          [foo setValue:value forKey:key];
      }
      

      并像下面这样调用它(来自您的示例):

      SomeValues *myBFSV = [SomeValues sharedInstance];
      NSString *Bar = [NSString stringWithString:@"Label1"];// this may not be necessary...
      NSLog(@"The string %@", Bar);
      [myBFSV SetBFSV:Bar ToVal:25]; // don't pass a decimal for a (long)
      

      【讨论】:

      • 谢谢斯蒂芬,你是对的,我确实需要阅读更多关于指针和对象的信息。无论如何,使用 (NSString *) 就可以了。我还将使用 double 而不是 long 并修复内存泄漏。再次感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多