2

I am working on an iOS SDK 4 project with ARC enabled.

My class MyTextView (derived from UITextView with UITextViewDelegate protocol) implements the following static method:

+ (void)showInViewController:(UIViewController*)viewController
{
    MyTextView *textEdit = [[MyTextView alloc] init];
    textEdit.delegate = textEdit;
    [viewController.view addSubview:textEdit];

    // Show the keyboard
    [textEdit becomeFirstResponder];
}

In one of my view controllers I call the following:

[MyTextView showInViewController:self]

This crashes with warning: Unable to restore previously selected frame. on becomeFirstResponder. Looks like some stack related crash because of some cycle. I am fairly new to ARC. The delegate property of UITextView is defined as assign (shouldn't ARC interpret that as weak?). I know this approach is rather strange memory-wise. However, I wanted to know if ARC can handle things like that. Obviously it can't. Any idea what might be the problem and how to solve it?

nneonneo
  • 171,345
  • 36
  • 312
  • 383
Lars Schneider
  • 5,530
  • 4
  • 33
  • 58
  • 2
    Retain cycles generally don't cause crashes -- they just prevent objects from ever being deallocated. – Caleb Oct 28 '11 at 07:21
  • Thanks Caleb. I modified the title accordingly. – Lars Schneider Oct 28 '11 at 09:04
  • Not even sure enough to make this an answer, but maybe [super setDelegate:self]; solves it. – Aberrant Oct 28 '11 at 09:47
  • Problem seems to be that neither the delegate assignment nor the addSubview call will perform an "retain" on the textEdit object. Consequently it will be released at the end of the method. – Lars Schneider Oct 28 '11 at 10:07
  • 1
    Assign is not the same as weak. Weak is a lot like assign, but a weak variable becomes nil once all of it's strong references are released. – James Oct 28 '11 at 17:26
  • I'm not sure what the particular issue is, but this approach seems really problematic. Once you've executed `showInViewController:`, you have no reference to the MyTextView instance. It should be retained by its superview, but you have no good way to reference it, so you can't pass it messages or extract the value of the text. The only way to get a handle on it would be to walk it's superview's subviews. – Christopher Pickslay Oct 28 '11 at 21:02
  • An `assign` property will result in an `unsafe_unretained` property when compiling for iOS 4. – Alex Nichol Oct 28 '11 at 22:35
  • @chrispix: You are right - at least non-ARC wise. Actually, that was my solution. I keep a strong reference of the MyTextView object in the calling view controller. However, I just wondered if ARC can handle this stuff (but ARC is no garbage collection after all). – Lars Schneider Oct 29 '11 at 08:22
  • How do you keep a strong reference to the MyTextView object? You create it by calling a class method which returns void. – Christopher Pickslay Oct 30 '11 at 16:51
  • 1
    @chrispix: No, I changed the class method to return a pointer to the actual object. – Lars Schneider Oct 31 '11 at 09:24
  • You should update the code in the question then. – Christopher Pickslay Nov 01 '11 at 16:48
  • This is an odd pattern (having a view be its own delegate) but that aside, check whether that is the issue by commenting out the line setting the delegate (i.e. no delegate is set) and see if the crash still occurs. – XJones Mar 09 '13 at 18:23

2 Answers2

1

I don't think it has anything to do with the ARC and memory management, but just a more fundamental problem that a UITextView cannot be a delegate of itself. It gets locked in a loop. Put a logging message in textViewDidChangeSelection and you'll see it gets repeatedly invoked. Not a memory issue, methinks, but rather just a logic issue with UITextView delegates. Even if you don't do your problematic showInViewController but just create a standard UITextView subclass and try to set its delegate to itself, you'll see the same curious behavior.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

old post, but here is the answer:

http://www.cocoabuilder.com/archive/cocoa/282093-uitextview-as-its-own-delegate-infinite-loop-on-keyboard-select.html

or here aswell

self.delegate = self; what's wrong in doing that?

Community
  • 1
  • 1
Pochi
  • 13,391
  • 3
  • 64
  • 104