1

As written in the title, I have a property to a UITextField. I add this UITextField to the UIView.

If I have a strong pointer, the UITextField appears,

If I have a weak pointer, the UITextField doesn't appear.

What goes wrong when I have a weak pointer? I did the same with UIButton and then it actually appears (with strong and weak pointer).

Here's some code:

CreateCategoryView.h

@interface CreateCategoryView : UIView 

@property (weak, nonatomic) UITextField *nameTextField;

@end

CreateCategoryView.m

@implementation CreateCategoryView

- (id)initWithFrame:(CGRect)frame andParent {
    self = [super initWithFrame:frame];
    if (self) {
        self.nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(5, 30, 310, 25)];
        self.nameTextField.borderStyle = UITextBorderStyleRoundedRect;
        self.nameTextField.textColor = [UIColor blackColor];
        self.nameTextField.backgroundColor = [UIColor whiteColor];
        [self addSubview:self.nameTextField];
    }
    return self;
}

@end
tkanzakic
  • 5,499
  • 16
  • 34
  • 41
c2programming
  • 235
  • 3
  • 17

4 Answers4

5

You should create the text field with a local variable (which is strong by default), and then assign it to your property. There's no need to use a strong reference to the text field since the view you're adding it to keeps a strong reference.

- (id)initWithFrame:(CGRect)frame  {
    self = [super initWithFrame:frame];
    if (self) {
        UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(5, 30, 310, 25)];
        tf.borderStyle = UITextBorderStyleRoundedRect;
        tf.textColor = [UIColor blackColor];
        tf.backgroundColor = [UIColor whiteColor];
        _nameTextField = tf;
        [self addSubview:_nameTextField];
    }
    return self;
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • @c2programming, It looks like when you create a button with buttonWithType: it gets another retain when adding a subview to itself, so it gets a retain count of 2, one is decremented because of the weak pointer, but there's still one left for it to live long enough to get retained by its superview. – rdelmar Dec 15 '12 at 23:20
  • Careful: The compiler may release `tf` right after the expression where it is last used, so `_nameTextField` may still be `nil` when adding the sub view. To be on the safe side, use `[self addSubview:tf]` instead of [self addSubview:_nameTextField`. – Tammo Freese Dec 17 '12 at 16:40
3

The accepted answer is wrong.

The issue is that the view is released immediately after it is created. You can see this by doing the following

__weak UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];

With this the compiler will complain with

warning: assigning retained object to weak variable; object will be released after assignment

What you need to do is have a temporary strong variable, which as @rdelmar points out local variables are by default

So

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];

would be equivalent to

__strong UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];

which will keep the view alive long enough to be owned by the view calling addSubview

Paul.s
  • 38,494
  • 5
  • 70
  • 88
0

The Apple document has an example on this

Weak variables can be a source of confusion, particularly in code like this:

NSObject * __weak someObject = [[NSObject alloc] init];

In this example, the newly allocated object has no strong references to it, so it is immediately deallocated and someObject is set to nil.

Dino Tw
  • 3,167
  • 4
  • 34
  • 48
-1

The object is not retained since it's a weak pointer so your text field is released right after it's initialized. Use a weak property to point to a strong object so that object stays retained.

Alex L
  • 8,419
  • 6
  • 43
  • 51
  • This doesn't quite make sense. The `-addSubview:` call should cause the parent view to retain the text field. – paulmelnikow Dec 15 '12 at 21:47
  • I tested the same with a UIButton (weak pointer, then added it to the UIView) and with the UIButton it works. So there must be something else going wrong, right? – c2programming Dec 15 '12 at 21:52
  • if addSubview retained the text field we wouldn't need strong properties for any UI class. It does not. It's up to you to retain it and as soon as view retain count hit 0 it removes itself from any superview. You should use strong pointers when you want to own the object. Weak properties can be used when you don't want to be the last holding the object. Having a delegate property on some of your classes is a good example. You often don't want to be the last holding the delegate class. – demosten Dec 15 '12 at 21:57
  • but why does it work with UIButton. I mean also call addSubview: for the UIButton as well -> And there it works – c2programming Dec 15 '12 at 22:02
  • I thought it did do a retain. Check this post http://stackoverflow.com/questions/4163908/does-addsubview-increment-retain-count – Luc Wollants Dec 15 '12 at 22:02
  • 1
    This answer isn't correct. The text field is actually deallocated right after it's created (because of the weak reference), not at the end of the init method. The text field should be created with a local variable, then assigned to the property, if you want to use a weak reference, which should be fine since the view it's being added to will keep a strong reference. – rdelmar Dec 15 '12 at 22:26
  • @c2programming, did you do it exactly the same way with the button? – rdelmar Dec 15 '12 at 22:29
  • 1
    @demosten your comment is wrong. `addSubview` will actually take a retain on the subview. The issue here is that the object is not kept alive long enough to even get to that call. You can see this by making a local variable `__weak UIView *view = [[UIView alloc] initWithFrame:f];` and seeing the compiler complain with `Assigning retained object to a weak variable; object will be released after assignment` – Paul.s Dec 15 '12 at 22:42
  • @demosten: Superviews retain their subviews. If they didn't, you'd need a strong reference to every single view in your hierarchy, which is ridiculous as there are hundreds, if not thousands, of views which exist in the hierarchy of the average application (most of which never need to be manipulated.) – Jonathan Grynspan Dec 15 '12 at 22:57
  • 1
    Yes it looks I'm wrong there. I'll get deeper into it but Paus.s's comment makes sense. Useful discussion. I'll keep my comment not to break it. – demosten Dec 15 '12 at 23:06