Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c EXC_对我保留、使用、然后释放的警报视图对象的错误访问_Objective C_Ios_Memory Management - Fatal编程技术网

Objective c EXC_对我保留、使用、然后释放的警报视图对象的错误访问

Objective c EXC_对我保留、使用、然后释放的警报视图对象的错误访问,objective-c,ios,memory-management,Objective C,Ios,Memory Management,我知道这是一个常见的问题,所以我需要一个解释,这样我就不会一直有这个问题。在我的头文件中,我定义了UIAlertView并将其保留,如图所示: @interface myController { UIAlertView *alert; } @property (nonatomic, retain) UIAlertView *alert; 在我的实现中,我使用并重用此警报,如下所示: @synthesize alert; ... if (self.alert != nil

我知道这是一个常见的问题,所以我需要一个解释,这样我就不会一直有这个问题。在我的头文件中,我定义了UIAlertView并将其保留,如图所示:

@interface myController {
    UIAlertView *alert;
}

@property (nonatomic, retain) UIAlertView *alert;
在我的实现中,我使用并重用此警报,如下所示:

@synthesize alert;

 ...

    if (self.alert != nil) {
        [self.alert release];
    }

    self.alert = [[UIAlertView alloc] initWithTitle:title 
                                       message:message
                                      delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: @"Ok To Send", nil];

    [self.alert show];
我也在我的dealloc中发布了这个

所以,我听过关于内存管理的黄金法则,但我显然不明白。黄金法则说,你绝不能释放你没有保留或通过alloc获得的对象。您必须始终最终释放通过alloc保留或获得的对象

我在头文件中保留了它,所以我最终必须在dealoc中发布它。在我的实现中,我不止一次地执行alert对象的alloc,因此每次准备重新alloc时,我都会释放旧的alloc对象


请帮助我理解我的误解。

您的财产保留。所以当你设定自我时,它会为你保留。同样,当您将属性设置为nil或其他对象时,它将释放旧的属性对象。

您的属性将保留。所以当你设定自我时,它会为你保留。同样,当您将属性设置为nil或其他对象时,它会释放旧的属性对象。

看起来您是在双重保留警报! self.alert执行retain操作,自使用alloc init实例化以来,您的对象已重新计入1

试试这个:

//if (self.alert != nil) {
//    [self.alert release];
//}

self.alert = nil;

alert = [[UIAlertView alloc] initWithTitle:title 
                                   message:message
                                  delegate:self
cancelButtonTitle:@"Cancel" otherButtonTitles: @"Ok To Send", nil];

[self.alert show];

相反

看来你在加倍保持警惕! self.alert执行retain操作,自使用alloc init实例化以来,您的对象已重新计入1

试试这个:

//if (self.alert != nil) {
//    [self.alert release];
//}

self.alert = nil;

alert = [[UIAlertView alloc] initWithTitle:title 
                                   message:message
                                  delegate:self
cancelButtonTitle:@"Cancel" otherButtonTitles: @"Ok To Send", nil];

[self.alert show];

相反

指定了带有
retain
@属性
实现如下内容

-(void)setAlert:(UIAlertView*)alert
{
        if (self->alert != alert)
        {
                [self->alert release];
                self->alert = [alert retain];
        }
}
因此,通过为属性指定一个新值,该属性将处理前一个值的
release
。。。因此,当您手动
释放它时,您就过度释放了

此外,由于已将
@属性
设置为
保留
,因此在分配给属性之前,应
自动释放

self.alert = [[[UIAlertView alloc] initWithTitle:title 
                                         message:message
                                        delegate:self cancelButtonTitle:@"Cancel"  
                               otherButtonTitles: @"Ok To Send", nil] autorelease];

[self.alert show];

指定了带有
retain
@属性
是这样实现的

-(void)setAlert:(UIAlertView*)alert
{
        if (self->alert != alert)
        {
                [self->alert release];
                self->alert = [alert retain];
        }
}
因此,通过为属性指定一个新值,该属性将处理前一个值的
release
。。。因此,当您手动
释放它时,您就过度释放了

此外,由于已将
@属性
设置为
保留
,因此在分配给属性之前,应
自动释放

self.alert = [[[UIAlertView alloc] initWithTitle:title 
                                         message:message
                                        delegate:self cancelButtonTitle:@"Cancel"  
                               otherButtonTitles: @"Ok To Send", nil] autorelease];

[self.alert show];

在我看来,这是一个“经典”案例,您不需要属性(除非您需要从另一个类访问警报…),或者是alertView代理,公平地说,我认为他也不需要,因为我没有看到列出任何协议。在我看来,这是一个“经典”案例,您不需要属性(除非您需要从其他类访问警报…)或者是alertView代表,公平地说,我认为他也不是,因为我没有看到列出任何协议。太棒了。非常感谢你的解释。我一次又一次地被它困扰着。非常感谢你的解释。我一次又一次地被它困扰着