开发者

An NSMutableArray that doesn't retain?

A few UIViewControllers in my app that need to register with a "provider" class in their viewDidLoad methods. 开发者_如何学运维I've just been adding them to an NSMutableArray contained in the provider class.

However, I don't want this NSMutableArray to keep them from being dealloc'ed, and I also want to have them remove themselves from the NSMutableArray in their dealloc methods.

I tried just issuing a [self release] after adding them to the array, and this works, but in order to avoid a crash when they get dealloc'ed, I have to issue a [self retain] right before I remove them. It seems like I'm doing something horribly wrong by retaining an object in it's own dealloc method.

Is there a better way to store these values?


You just can't do it the way you want because you would have a circular dependency. You cannot dealloc an object that is in an NSArray.

You'll need to have them explicitly remove themselves from the array at some point in their life cycle, or just leave them there and let them get deallocated when the array gets deallocated.


One of the main rules of reference counting memory is that you should only deal with any retains that are yours to begin with. In this case, releasing to counter-balance a retain by the array breaks that rule.

A better alternative would be instead of releasing it and having it remove itself from the array, perform the opposite. After you add it to the array, make sure to release any retains you have on it so that the only object owning it is the array itself. Then, when you want to get rid of the object, instead of releasing it, remove it from the array.

You should also look at how the notification API is setup. It has a similar setup of items 'registering' with the center, then needing to be removed, so you can try and rework your provider class to something like that.


My hunch tells me that the "provider" class should be adding things to its own array. It sounds weird to have the UIViewControllers adding themselves to their owners.

Instead of something like:

-(void)viewDidLoad {
    ...
    [self.provider registerViewController:self];
    ...
}

Do this in the provider class:

view = [[MyViewController alloc] init...];
[self registerViewController:view];

If the provider needs to know when the view controller shuts down, make it a delegate:

viewController = [[MyViewController alloc] init...];
[self registerViewController:viewController];
viewController.delegate = self;

The callback will look something like this inside of the UIViewController:

[self.delegate myViewControllerHasFinished:self];

And the provider will do this:

-(void)myViewControllerHasFinished:(MyViewController *)vc {
   [self unregisterViewController:vc];
}


I think you should rethink this. Maybe have the VC register with the provider in viewWillAppear and unregister in viewDidDisappear?

EDIT -- This answer mentions a way to get NSDictionary that doesn't retain, maybe you can use it for NSArray also (if you still want to go that route). Look at CFArray, in the CFArrayCreate operations, callBacks parameter.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜