开发者

Why do I lose access to this instance variable?

开发者 https://www.devze.com 2023-04-01 02:20 出处:网络
zURL is declared like: .h: @interface PanelController : NSWindowController <NSWindowDelegate> { NSURL *zURL;

zURL is declared like:

.h:

@interface PanelController : NSWindowController <NSWindowDelegate>
{
    NSURL *zURL;
}

@property (nonatomic, copy) NSURL *zURL;

.m:

@synthesize zURL;

In one IBAction I have:

 - (IBAction)openBrowser:(id)sender {
    NSOpenPanel *zOpenPanel = [NSOpenPanel openPanel];
    [zOpenPanel setCanChooseFiles: TRUE];
    [zOpenPanel setCanChooseDirectories: TRUE];
    [zOpenPanel setAllowsMultipleSelection: TR开发者_JS百科UE];
    [zOpenPanel setLevel:CGShieldingWindowLevel()];
    NSInteger zIntResult = [zOpenPanel runModal];
    if (zIntResult == NSFileHandlingPanelCancelButton) {
        return;
    } 

    // zURL set here
    zURL = [NSURL alloc];
    zURL = [zOpenPanel URL];
    NSLog(@"url = %@", zURL); // works

    NSString *zStr = [zURL absoluteString];
    _fileField.stringValue = zStr;
    [_importButton setEnabled:TRUE];
    [self openPanel];
}

In the next IBAction:

NSLog(@"url = %@", zURL); // EXC_BAD_ACCESS error


You are assigning your URL to zOpenPanel's URL attribute, but not indicating you intend to keep the reference by retaining it.

zURL = [NSURL alloc]; // assign my variable to a new URL, allocating memory

your second line replaces your reference with a reference to zOpenPanel's URL attribute, leaking the URL you just created above.

at some point later, zOpenPanel tells the OS it is done with its URL, and frees the ram thus invalidating your reference.

what you're probably trying to do:

zURL = [[zOpenPanel URL] retain];

this assigns your reference to zOpenPanel's URL attribute and tells the OS you want partial ownership of it's lifetime.

when you are done with zURL you will need to release it and relinquish your claim on it's lifetime:

[zURL release];

edit:

since you're declaring it as a property on your class, you should use the property notation to invoke the appropriate behavior:

self.zURL = [zOpenPanel URL];

since you've declared the property to have copy semantics, this will copy the URL, and you will still need to release it in your dealloc.


In the first line you are allocating an NSURL, but not calling an initializer. In the second line you are assigning zURL from another place, losing the pointer to the object you created in the first line (which is a memory leak).

Where is zURL stored? Is it an instance variable? If so, you have not retained what was returned from [zOpenPanel URL] so you cannot be guaranteed that the object was not released by the time you get called in an IBAction.


I suspect your zURL var is being released at some point, as George has pointed out it would be helpful if you posted how zURL is being declared.

Additionally, you shouldn't need to perform [NSURL alloc] if you are immediately replacing the value of zURL on the next line.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号