OC手动管理内存时出现程序崩溃

今天写程序时程序崩溃了,调试了很久才找到了问题所在,一下是对这次问题的总结,希望对跟我这样的新手有所帮助。如下:


在手动管理内存时应该注意,实例变量在定义为 retain 模式时,在调用初始化方法中不应该是自己手动赋值,而是调用setter方法。何为手动赋值?见下面:

在头文件中声明 

@property (nonatomic, retain, getter = name) NSString *_name;

这里本意是想在 _name 每次赋值引用计数加1。而在 .m 文件中如果初始化方法写成:

- (id) initWithName:(NSString*)name
{
     _name = name;
}

的话,是不对的。因为此时并没有调用 setter 方法,而是手动的赋值了,所以引用计数值不会加1。如在其他地方写如下语句:

//注:_per 为在某个类定义的实例变量

- (void) hello
{ 
     NSString *str = [NSString stringWithString:@“hello”];     //retainCount 为 1
     _per = [[Person alloc] initWithName:str];     //引用计数不增加,还是1
     [str release];               //str销毁, per 中的 _name 成为野指针。如果再操作它就回导致程序崩溃。
}

当[str release] 执行后, _per.name 已经成为野指针。 即使执行 [str release]语句,当此函数一执行完,str也会被回收, per 中的 _name 也还是会成为野指针。如果再次使用 per.name 可能导致程序崩溃或得不到想要的结果,原因是:如果在调用 per.name 之前没有其他申请空间的操作,则可能会得到正确的结果,但是此时已经是不安全的数据了。如果在调用 per.name之前有其他申请空间的操作,那就会可能覆盖了之前 str 所使用的地址的内容,此时如果申请空间的还是NSString*类型,那之后使用 per.name 时就会得到错误的结果,而如果此时申请空间的是其他对象类型,那就会导致程序崩溃。
如:

a. 在hello方法后面增加如下语句 或 在hello方法结束后紧接着执行的另一个方法中的语句:

NSString *newStr = [NSString stringWithString:@“nihao”];          //此时可能使用的就是刚才 str 的地址空间
NSLog(@“%@“, _per.name);               //输出nihao


b. 在hello方法后面增加如下语句 或 在hello方法结束后紧接着执行的另一个方法中的语句:

UILable *lable = [[UILable alloc] init];          //此时可能使用就是刚才 str 的地址空间
NSLog(@“%@“, _per.name);          //程序崩溃


所以,在初始化方法中应该写成 self._name ,这样才是调用setter方法

以上是我今天遇到错误解决后的心得,有说错的地方求批斗指出!

你可能感兴趣的:(内存管理,崩溃)