Iphone 目标NSC字符串以单件形式发布
我正在构建一个小型iphone应用程序,并使用一个单例来存储和更新一个字符串,当用户点击屏幕上的字母或数字以形成代码时,该字符串会被更新 i、 e.他们点击3,然后点击S,然后点击4,我需要跟踪并组合输入,给我“3S4”的发言权。初始化singleton时,它会创建一个空NSString,然后我使用stringByAppendString方法添加下一个字母/数字。当我第一次尝试这一点时,我没有[enteredCode retain]行,应用程序将在EXC_BAD_访问时崩溃,总是在两次输入之后。我设置了NSZombie属性,它告诉我输入的代码已被取消分配,但我不知道在哪里或如何发生。我所知道的是,在addInput方法的末尾,它将报告retainCount为2,然后在我看到后(通过从其他地方调用singleton),它将下降到1(当retain行在那里时) 我的问题是:虽然我通过添加[enteredCode retain]所做的工作对我有效,但我是否违反了一些规则,或者以错误/糟糕的方式进行了这些工作?我就是不明白为什么要释放这个字符串 顺便说一句,我是Objective-C的新手 在迈辛格尔顿Iphone 目标NSC字符串以单件形式发布,iphone,objective-c,nsstring,Iphone,Objective C,Nsstring,我正在构建一个小型iphone应用程序,并使用一个单例来存储和更新一个字符串,当用户点击屏幕上的字母或数字以形成代码时,该字符串会被更新 i、 e.他们点击3,然后点击S,然后点击4,我需要跟踪并组合输入,给我“3S4”的发言权。初始化singleton时,它会创建一个空NSString,然后我使用stringByAppendString方法添加下一个字母/数字。当我第一次尝试这一点时,我没有[enteredCode retain]行,应用程序将在EXC_BAD_访问时崩溃,总是在两次输入之后。
@interface MySingleton : NSObject {
NSString *enteredCode;
}
在迈辛格尔顿
-(void) addInput:(NSString *) input
{
NSLog(@"enteredCode retain count is : %d \n ",[enteredCode retainCount]);
enteredCode = [enteredCode stringByAppendingString:input];
NSLog(@"enteredCode retain count is : %d \n ",[enteredCode retainCount]);
[enteredCode retain]; // without this the app crashes
NSLog(@"enteredCode retain count is : %d \n ",[enteredCode retainCount]);
}
-(id) init
{
self = [super init];
if (self)
{
enteredCode = @"";
}
return self;
}
首先,切勿使用
-retainCount
方法。对象上保留的绝对计数是框架的实现细节,通常会返回令人困惑的结果
保留计数是您应该完全作为一组平衡的增量来维护的。如果要将保留计数添加到某个对象,则必须释放该对象或自动释放该对象。故事结束了
这个
有了这些知识,崩溃的根源是一个相当常见的内存管理错误
enteredCode = [enteredCode stringByAppendingString:input];
每次执行该行代码时,您都将用NSString的自动删除实例替换enteredCode
。自动释放池已耗尽,下次使用enteredCode
时,程序将崩溃
您保留enteredCode
的解决方案只是解决方案的一半。您需要确保enteredCode
的原始值也已释放。请参阅内存管理文档
如果这是我的应用程序,我会将enteredCode
转换为一个@property,它复制字符串,并始终通过该属性设置和访问enteredCode
,在我的代码中从不手动保留或释放它(当然,在-dealoc
之外)。首先,不要使用-retainCount
方法。对象上保留的绝对计数是框架的实现细节,通常会返回令人困惑的结果
保留计数是您应该完全作为一组平衡的增量来维护的。如果要将保留计数添加到某个对象,则必须释放该对象或自动释放该对象。故事结束了
这个
有了这些知识,崩溃的根源是一个相当常见的内存管理错误
enteredCode = [enteredCode stringByAppendingString:input];
每次执行该行代码时,您都将用NSString的自动删除实例替换enteredCode
。自动释放池已耗尽,下次使用enteredCode
时,程序将崩溃
您保留enteredCode
的解决方案只是解决方案的一半。您需要确保enteredCode
的原始值也已释放。请参阅内存管理文档
如果这是我的应用程序,我会将enteredCode
转换为一个@property,它复制字符串,并始终通过该属性设置和访问enteredCode
,而不会在我的代码中手动保留或释放它(当然,在-dealoc
之外)。您正在使用stringByAppendingString:
重新定义现有字符串,这导致了保留问题。(或者,使用NSMutableString,您可以避免这种情况。)
顺便说一下,您可以在init
覆盖中执行if(self=[super init])
。如果声明发生或可能发生,则返回true。NSString的stringByAppendingString:
返回通过将一个字符串附加到另一个字符串而生成的新NSString,并且新NSString设置为autorelease,这会清空autorelease池,下次运行会使应用程序崩溃。您正在使用stringByAppendingString:
重新定义现有字符串,这导致了保留问题。(或者,使用NSMutableString,您可以避免这种情况。)
顺便说一下,您可以在init
覆盖中执行if(self=[super init])
。如果声明发生或可能发生,则返回true。以下是代码的外观:
@interface MySingleton : NSObject {
NSString *enteredCode;
}
@property (nonatomic, retain) NSString *enteredCode;
@end
@synthesize enteredCode;
-(void) addInput:(NSString *) input
{
self.enteredCode = [self.enteredCode stringByAppendingString:input];
}
- (void)dealloc {
[enteredCode release];
}
@end
下面是代码的外观:
@interface MySingleton : NSObject {
NSString *enteredCode;
}
@property (nonatomic, retain) NSString *enteredCode;
@end
@synthesize enteredCode;
-(void) addInput:(NSString *) input
{
self.enteredCode = [self.enteredCode stringByAppendingString:input];
}
- (void)dealloc {
[enteredCode release];
}
@end
释放字符串文字是可以的,它与释放任何其他NSString没有什么不同。当然,但它永远不会被保留,因此您不应该(也不应该)释放它。释放未分配的内容可能会导致严重问题。enteredCode属性会被保留。enteredCode
iVar要么为零,要么由singleton类保留。不管是哪种方式,释放对象都是好的(而且是必需的)。我认为对保留属性如何工作的误解是否决票的来源。如果我的回答中还有其他问题,请让我知道。释放字符串文字是可以的,这与释放任何其他NSString没有什么不同。当然,但它永远不会被保留,所以你不应该(也不应该)释放它。释放未分配的内容可能会导致严重问题。enteredCode属性被保留。输入的代码