0
votes

I have an iPad app with a main ViewController, and inside of it I have a UIButton. This is tied to a segue with style Popover with a target that is a UIPopoverController class (empty, from Xcode's 'create new' with UIPopoverController subclass).

When I click the button, the segue executes, and it crashes:

2012-12-22 16:58:57.275 iAmFrustratedApp[11521:c07] -[MyGreatPopoverController initWithCoder:]: unrecognized selector sent to instance 0x1caabe70
2012-12-22 16:58:57.277 iAmFrustratedApp[11521:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyGreatPopoverController initWithCoder:]: unrecognized selector sent to instance 0x1caabe70'
*** First throw call stack:
(0x22fe012 0x148fe7e 0x23894bd 0x22edbbc 0x22ed94e 0x5f3ae9 0x702a02 0x7020e5 0x5f367b 0x702a02 0x702418 0x7020e5 0x5f2aa3 0x81e48a 0x81ea83 0x81eb54 0x14a3705 0x3da920 0x3da8b8 0x49b671 0x49bbcf 0x49ad38 0x40a33f 0x40a552 0x3e83aa 0x3d9cf8 0x1bacdf9 0x2281f3f 0x228196f 0x22a4734 0x22a3f44 0x22a3e1b 0x1bab7e3 0x1bab668 0x3d765c 0x1cbd 0x1be5)
libc++abi.dylib: terminate called throwing an exception

Interestingly, I used to have this target be a normal UIViewController. When it was that class, this worked properly, except that I couldn't dismiss the popover programmatically in any way. That's the only reason I switched the target class to be UIPopoverController.

1
It appears you've set something's class to MyGreatPopoverController in the Storyboard. UIPopoverController does not conform to NSCodingCodaFi
Correct -- I have set a class up that acts like what's inside the popover. It used to be a subclass of UIVC, which I created in IB. Then I went to the class definition and changed : UIViewController to : UIPopoverController. Is this the source of my grief? Why won't this work?Nektarios
It won't work because UIPopoverController cannot be instantiated from a NIB (that was why I made that quip about NSCoding, that's the whole reason the protocol exists: is to dearchive objects from nibs)CodaFi

1 Answers

2
votes

From NSCoding Protocol Ref:

The NSCoding protocol declares the two methods that a class must implement so that instances of that class can be encoded and decoded. This capability provides the basis for archiving (where objects and other structures are stored on disk) and distribution (where objects are copied to different address spaces).

A coder instructs the object to do so by invoking encodeWithCoder: or initWithCoder:. encodeWithCoder: instructs the object to encode its instance variables to the coder provided; an object can receive this method any number of times. initWithCoder: instructs the object to initialize itself from data in the coder provided; as such, it replaces any other initialization method and is sent only once per object. Any object class that should be codable must adopt the NSCoding protocol and implement its methods.

A xib file is just an archive made of encoded objects. When you load a xib, the framework decodes them back (through initWithCoder) into objects that populate your app.

Now, it happens that UIPopoverController does not conform to the NSCoding protocol (see the reference document, just at the beginning, where it says: "Conforms to": no NSCoding is listed there.)

But:

Any object class that should be codable must adopt the NSCoding protocol and implement its methods.

Hence, when the framework finds you UIPopoverController derived class instance and tries to decode it, it fails.

Hope this clarifies it.