使用在Yosemite上运行的XCode 6.0.1。我有一个属性被设置为用户键入文本框的值,例如“090”。
//
// AppController.h
//
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "ORSSerialPort.h"
#import "ORSSerialPortManager.h"
@class ORSSerialPortManager;
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_7)
@protocol NSUserNotificationCenterDelegate <NSObject>
@end
#endif
@interface AppController : NSObject <ORSSerialPortDelegate,NSUserNotificationCenterDelegate>
@property (nonatomic, retain) NSString *hdgVal;
- (void)printHdg;
@end
稍后,我需要整数值进行比较。在标记为“CRASH HERE”的行中,当我点击hdgVal时,气泡会显示“class name = _NSArrayI”。点击眼球,表示值为10,10,0。
//
// AppController.m
//
#import "AppController.h"
@implementation AppController
@synthesize hdgVal;
- (void)startTimer
{
hdgTimer = [NSTimer scheduledTimerWithTimeInterval:0.6
target:self
selector:@selector(printHdg)
userInfo:nil
repeats:YES];
}
- (void)printHdg
{
NSInteger currH = [labelCurrHdg integerValue];
NSInteger wantedH = [hdgVal integerValue]; <== CRASH HERE
NSData *dataToSend;
NSString *str;
if (currH > wantedH - 3 && currH < wantedH + 3) {
[hdgTimer invalidate];
hdgTimer = nil;
[labelCurrHdg setStringValue:hdgVal];
[labelCurrHdg needsDisplay];
NSLog(@"Stopping timer");
return;
}
填写hdgVal的代码
- (IBAction)send:(id)sender
{
NSString *sendString = @"";
NSString *tmpStr;
NSString *tmpVal;
NSData *dataToSend;
int i;
int c;
char j;
if([sender tag] ==1)
{
NSButton *btn=(NSButton *)sender;
[btn setTitle:([btn.title isEqualToString:@"LP"] ? @"SP" : @"LP")];
i = [inputTextField intValue];
if(i < 181)
{
i = i + 180;
}
else if (i > 180)
{
i = i - 180;
}
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setPaddingPosition:NSNumberFormatterPadBeforePrefix];
[numberFormatter setPaddingCharacter:@"0"];
[numberFormatter setMinimumIntegerDigits:3];
NSNumber * number = [NSNumber numberWithInt:i];
tmpStr = [numberFormatter stringFromNumber:number];
[numberFormatter release];
[inputTextField setStringValue:tmpStr];
hdgVal = tmpStr;
}
else if([sender tag] == 0)
{
[buttonLP setTitle:@"LP"];
tmpStr = [inputTextField stringValue];
while([tmpStr length] < 3)
{
tmpStr = [@"0" stringByAppendingString:tmpStr];
}
[inputTextField setStringValue:tmpStr];
hdgVal = tmpStr;
}
else if([sender tag] ==3)
{
NSButton *btn=(NSButton *)sender;
[btn setTitle:([btn.title isEqualToString:@"LP"] ? @"SP" : @"LP")];
i = [inputTextField2 intValue];
if(i < 181)
{
i = i + 180;
}
else if (i > 180)
{
i = i - 180;
}
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setPaddingPosition:NSNumberFormatterPadBeforePrefix];
[numberFormatter setPaddingCharacter:@"0"];
[numberFormatter setMinimumIntegerDigits:3];
NSNumber * number = [NSNumber numberWithInt:i];
tmpStr = [numberFormatter stringFromNumber:number];
[numberFormatter release];
[inputTextField2 setStringValue:tmpStr];
hdgVal = tmpStr;
}
else if([sender tag] == 2)
{
[buttonLP2 setTitle:@"LP"];
tmpStr = [inputTextField2 stringValue];
while([tmpStr length] < 3)
{
tmpStr = [@"0" stringByAppendingString:tmpStr];
}
[inputTextField2 setStringValue:tmpStr];
hdgVal = tmpStr;
}
switch(rotorSelected)
{
case 1: //Alfaspid and Yaesu
case 7:
sendString = @"M";
sendString = [sendString stringByAppendingString:(hdgVal)];
sendString = [sendString stringByAppendingString:@"\r\n"];
dataToSend = [sendString dataUsingEncoding:NSUTF8StringEncoding];
[serialPort sendData:dataToSend];
break;
case 2: //DCU
sendString = @"AP1";
sendString = [sendString stringByAppendingString:(hdgVal)];
sendString = [sendString stringByAppendingString:@";AM1;"];
NSLog(@"SendString = %@", sendString);
dataToSend = [sendString dataUsingEncoding:NSUTF8StringEncoding];
[serialPort sendData:dataToSend];
if (!hdgTimer)
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
[self startTimer];
}
break;
case 3: //Prosistel A B C
c = 2;
j = (char)c;
tmpVal = [NSString stringWithFormat:@"%c", j];
dataToSend = [tmpVal dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
tmpStr = [inputTextField stringValue];
for (i = 0 ; i < [tmpStr length]; i++)
{
NSLog(@"Iteration: %d", i);
tmpVal = [tmpStr substringWithRange:NSMakeRange(i, 1)];
c = [tmpVal intValue];
j = (char)c;
tmpVal = [NSString stringWithFormat:@"%c", j];
dataToSend = [tmpVal dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
}
c = 13;
j = (char)c;
dataToSend = [tmpVal dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
break;
case 4: //Prosistel CBOX/D
//char c = 0x02; dataToSend = [NSData dataWithBytes:&c length:1]
j = 0x02;
dataToSend = [NSData dataWithBytes:&j length:1];
[self.serialPort sendData:dataToSend];
tmpStr = @"AG";
tmpStr = [tmpStr stringByAppendingString:(hdgVal)];
dataToSend = [tmpStr dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
j = 0x0d;
dataToSend = [NSData dataWithBytes:&j length:1];
[self.serialPort sendData:dataToSend];
break;
case 5: //RC-2800PX
sendString = @"A#";
sendString = [sendString stringByAppendingString:(hdgVal)];
sendString = [sendString stringByAppendingString:@"\r"];
dataToSend = [sendString dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
break;
case 6: //SARTEK
sendString = @"P";
sendString = [sendString stringByAppendingString:(hdgVal)];
sendString = [sendString stringByAppendingString:@"\r\n"];
dataToSend = [sendString dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
break;
default:
break;
}
答案 0 :(得分:0)
问题是一个简单的内存管理问题。由于您使用的是MRC(为什么不使用ARC?),您需要确保正确保留分配给hdgVal
ivar的值。
最简单的解决方案(除了使用ARC)是将hdgVal
ivar的所有直接用法替换为对hdgVal
属性的引用。
变化:
hdgVal = tmpStr; // direct ivar access, no retain called
为:
self.hdgVal = tmpStr; // use the property, value retained
您拥有的代码是将自动释放的字符串直接分配给ivar。一旦原始字符串被释放,您的ivar指向垃圾,然后指向其他一些任意值。在你发布的情况下,NSArray
恰巧正在使用该内存。