Dav*_*ave 1 iphone cocoa objective-c
我花了最后3个小时试图找出这个错误.我希望有人向我解释,所以我不再这样做了.
我没有使用"self"就分配了一个NSString实例变量.当类("self")发布时,我收到了"错误访问"错误.我在另一个具有相同变量声明的类中完成了同样的事情并且没有此错误.以下是我的代码.我注释掉了破坏的线,下面的线修复了它.但我不明白为什么......请注意,还有其他实例变量不会导致此问题.在分配实例变量时,我是否应始终使用"self"保留字?请告诉我.
声明
@property (nonatomic, readonly, assign) int IID;
@property (nonatomic, assign) int ProfileIID;
@property (nonatomic, retain) NSDate *NoteDate;
@property (nonatomic, copy) NSString *NoteText;
Run Code Online (Sandbox Code Playgroud)
代码段
// the default date format is Year-Month-Day
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
[df setDateFormat:kDateFormat];
IID = sqlite3_column_int(selectstmt, 0);
ProfileIID = sqlite3_column_int(selectstmt, 1);
// notice this does not cause a memory error
NoteDate = [[df dateFromString: [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)]] retain];
// the following may be NULL. Checking using the sqlite3_column_text method
const char *columnText = (const char *)sqlite3_column_text(selectstmt, 3);
if(columnText != NULL)
{
// this causes a memory error
//NoteText = [NSString stringWithUTF8String: columnText ];
// this does not cause memory error
self.NoteText = [NSString stringWithUTF8String: columnText ];
}
Run Code Online (Sandbox Code Playgroud)
原因
NoteDate = [[df dateFromString: [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)]] retain];
Run Code Online (Sandbox Code Playgroud)
没问题是因为你保留了变量.既然你不分配的字符串,但叫stringWithUTF8String上NSString,你不采取变量的所有权,所以返回的字符串到你会被自动释放.但是,由于您保留它,这不会导致问题.
如果变量是自动释放的,那么它们会在自动释放池耗尽时释放,这会在每个事件结束时发生(有关自动释放池的详细信息,请参阅更多信息).这对于实例变量来说并不好,因为它需要在当前事件之后继续存在.
通过以下方式分配变量时:
NoteText = [NSString stringWithUTF8String: columnText];
Run Code Online (Sandbox Code Playgroud)
不会调用您的setter方法,因此不会保留返回的字符串(同样是自动释放的),因此在事件结束时由自动释放池释放.
将其称为:
self.NoteText = [NSString stringWithUTF8String: columnText];
Run Code Online (Sandbox Code Playgroud)
确实保留了字符串,因为该行是另一种写法:
[self setNoteText:[NSString stringWithUTF8String: columnText]];
Run Code Online (Sandbox Code Playgroud)
它调用你的setter方法并保留变量,防止它在当前事件结束时被释放.
| 归档时间: |
|
| 查看次数: |
1750 次 |
| 最近记录: |