微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

需要为指定了保留标志的属性调用保留

如何解决需要为指定了保留标志的属性调用保留

| 我是Objective-C的新手,并且像大多数新手一样,我对引用管理有疑问。 我编写了一个使用NSURLConnection下载数据的类。该代码类似于http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html中的Apple示例。唯一的区别是,receivedData变量声明为\“ @属性(非原子,保留)NSMutableData * receivedData; \”在.m文件中,我具有\“ @ synthesize receiveData = _receivedData; \”。 我有connectionStart函数,它开始下载数据。在此功能中,我有以下代码
if (theConnection) {
    // Create the NSMutableData to hold the received data.
    // receivedData is an instance variable declared elsewhere.
    self.receivedData = [NSMutableData data];
} else {
    // Inform the user that the connection Failed.
}
程序崩溃并显示以下消息:
2011-06-12 12:47:22.298 Webgallery[1212:207] *** -[NSConcreteMutableData release]: message sent to deallocated instance 0x118a6fe0
如果我将receiveData分配更改为以下代码
self.receivedData = [[NSMutableData data] retain];
然后,程序可以正常运行,并且没有检测到内存泄漏。 如您所见,我需要在NSMutableData上调用keep,并且我正在使用属性,该属性声明为\“ retain \”。 为什么会这样? 编辑:.m文件的完整内容
#import \"galleryData.h\"
#import \"XmlParser.h\"

@implementation galleryData

@synthesize receivedData = _receivedData;
@synthesize imagesData = _imagesData;
@synthesize delegate = _delegate;
@synthesize currentObjectType = _currentObjectType;
@synthesize currentObjectIndex = _currentObjectIndex;

- (id) init
{
    [super init];
    _imagesData = [[NSMutableArray alloc] init];    
    return self;
}


- (void) dealloc
{
     [_imagesData release];
    _imagesData = nil;
    [super dealloc];
}

- (void) connectionStart:(NSURL *)theURL
{
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:theURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];


    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    if (theConnection) {
        // Create the NSMutableData to hold the received data.
        // receivedData is an instance variable declared elsewhere.
        //ASK: Kodėl čia reikia daryti retain jei @property jau nustatyta retain?
        self.receivedData = [[NSMutableData data] retain];
    } else {
        // Inform the user that the connection Failed.
    }

}

- (void) startLoading
{
    NSLog(@\"Loading started\");

    self.currentObjectIndex = 0;
    self.currentObjectType = ObjectTypeXML;
    [self connectionStart:[NSURL URLWithString:@\"http://www.aleksandr.lt/gallery/data.xml\"]];

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self.receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [connection release];
    [self.receivedData release];

    NSLog(@\"Connection Failed! Error - %@ %@\",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [connection release];

    if (self.currentObjectType == ObjectTypeXML) {
        NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:self.receivedData];        
        XmlParser *parser = [[XmlParser alloc] initXmlParser:self.imagesData];

        [nsXmlParser setDelegate:parser];
        [nsXmlParser parse];        
        [nsXmlParser release];
        [parser release];

        [self.receivedData release];
        self.receivedData = nil;

        if ([self.imagesData count]) {
            self.currentObjectIndex = 0;
            self.currentObjectType = ObjectTypeThumbImage;
            ImageData *firstimage = [self.imagesData objectAtIndex:0];
            NSURL *theURL = [NSURL URLWithString:firstimage.thumbImageURL];
            [self connectionStart:theURL];
        } else {
            [self.delegate loadingFinished];
            return;
        }
    } else if (self.currentObjectType == ObjectTypeThumbImage) {
        ImageData *currentimage;
        currentimage = [self.imagesData objectAtIndex:self.currentObjectIndex];

        UIImage *thumbImage = [[UIImage alloc] initWithData:self.receivedData];

        if (thumbImage == nil) {
            NSLog(@\"image was not created\");
        }

        [currentimage setThumbImageScaled:thumbImage];

        [thumbImage release];
        [self.receivedData release];
        self.receivedData = nil;

        if (self.currentObjectIndex == ([self.imagesData count] - 1)) {
            [self.delegate loadingFinished];
            return;
        }

        self.currentObjectIndex++;

        currentimage = [self.imagesData objectAtIndex:self.currentObjectIndex];
        NSLog(@\"\'%@\'\",currentimage.thumbImageURL);
        NSURL *theURL = [NSURL URLWithString:currentimage.thumbImageURL];
        [self connectionStart:theURL];
    }
}

@end
    

解决方法

        不要调用
[self.receivedData release]
-这会使内部指针悬空。保留属性的全部意义在于它会释放自身。只要做
self.receivedData = nil
。     ,        这是您的问题:
    [self.receivedData release];
    self.receivedData = nil;
您将释放该属性两次(通过分配nil显式第一次,隐式第二次)。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。