Significance of IBOutlet Macro and Bindings - xcode

When I use bindings I don't need to include the IBOutlet macro.
Ex.
#property NSString* stringToBind
Why is this?
When do we use the IBOutlet macro and when do we leave it out? I am confused because I thought we include the IBOutlet macro to when we want to use it as an object with interface builder.
What would happen if linked to an object (like would would normally do with an outlet) but excluded the IBOutlet macro? In other words created an outlet without the IBOutlet macro? It is optional in all cases? Is it just used to make things easier, so that they are detected?
Thanks in advance

As far as the compiler and linked are concerned, IBOutlet is a no-op. More specifically it is #define'd to nothing. Xcode and Interface Builder use static code analysis to figure out what to do, but it will have no impact on compiling or linking.
The NIB that is generated contains the names of the properties to connect when it is loaded and those names are resolved the same way that all other properties are resolved.
If you remove IBOutlet from a property declaration introduces a risk that the next time the NIB is generated, the link connection won't be made. I am not sure how Interface Builder handles that.

Related

Swift subclassing UITextField issues

I've subclassed UITextField and added two variables and a convenience function. One variables holds a String key and the other holds a reference to another TextField which is used to create a custom tab order.
All good except I've run into a small problem. Using the storyboard I'm not able to bind the IBOutlet in the controller to the text field elements that implement this subclass even though they are both the same type. I've had to set the IBOutlet variable to be a UITextField type, bind them and then set the IBOutlet back to the subclass.
This all works in Xcode5 using Objective-C so I assume this is an issue with the beta of XCode6 but just wanted confirm I wasn't missing something.
I am also playing with swift.. I can share what I checked when faced some problems, you can check these. Not sure though it is the solution for your problem.
1. Check class defined for subclass and main class
2. Check delegates defined for text fields.
3. Check if prototyping can solve your problem.
Beta 2 Release of XCode 6 has resolved this issue.

Finding stray IBOutlets

Is there a good way to detect stray IBOutlets prior to running?
Like if I added this code:
#interface MyViewController()
#property (nonatomic, weak) IBOutlet UIView *magicView;
#end
Then I connected it in Interface Builder. Some time later, I remove the outlet but forget to remove it in, say, my iPad storyboard. When I run the app, it'll crash with a KVO error at runtime.
IB shows a warning on them, but you need to click each view controller and search for yellow exclamation points. I'd rather just see a list, compiler warnings, something more prominent.
Interface Builder saves to XML files that can be examined in with a text editor in an effort to find zombie connections.

Which object should I use in XCode IB?

I'm messing around with Xcode and Interface Builder. I want to make a timer or clock type app. What type of object should the numbers be? Just a 'Label'?
You could use a 'Label' (which is a modified NSTextField), or you could use an non-editable NSTextField or even a NSView with a custom drawing method.
If you're still learning, I suggest you use a Label and go from there.
When linking to your AppDelegate (or whatever object you're using), remember to create an IBOutlet on your property declaration so you can link your label, like so:
#property (nonatomic, assign) IBOutlet NSTextField *clockLabel;
And setup the clock value using the setStringValue: method:
[self.clockLabel setStringValue:myString];
If you just want to display the numbers, then UILabel will be just fine.
And, if you want some nice looks then i would recommend some nice graphics images for the numbers.

NSWindow property set with the assign attribute instead of the strong

I notice the Mac App template has create the following:
#interface AppDelegate : NSObject
#property (assign) IBOutlet NSWindow *window;
According to the ARC guidelines all top level object should use a strong property but instead this is using an assign property. Would someone explain why?
A window will generally be "owned" by File's Owner, which will usually be your NSApplication instance (for the main nib) or an instance of NSWindowController, not necessarily the app delegate or the window delegate. This is why it wouldn't be appropriate for the reference to be strong inside the delegate class.
In Mac OS/X 10.7, NSWindow (along with several other Cocoa classes) didn't support management via ARC, so declared properties to NSWindow had to be assign rather than strong or weak. See the Transitioning to ARC and Nib Object Life Cycle documents for a more detailed discussion. The basic answer is that you can't use ARC-managed references for objects that override the release and retain methods.
In 10.8, it looks like NSWindow isn't on that list, but Xcode is still generating the assign attribute rather than weak.

NIB, setValue:forKey and retain (iOS)

I know some mechanism of outlet connection when loading NIB, but I am not sure. So I'm asking some questions to ensure my knowledge. I assumed these things all true, but It's hard to find mention about these on reference documentation. Please point wrong and right things.
I have an IBOutlet defined like this: (Of course it's not recommended way)
#implementation
{
IBOutlet id var1;
}
#end
NIB loader (alloc | retain) & autorelease all top-level objects. So it will be dealloc on runloop turn ends without additional retain.
Connecting IBOutlets are done with KVC.
KVC uses accessor method primarily.
KVC uses setValue:forKey secondarily. And the IBOutlet will be handled by this method because there's no declared property or access method.
setValue:forKey retains the new value object.
setValue:forKey releases the old value object.
So top-level object connected to the IBOutlet will be retained once. So I have to release it to dealloc. This is why I must release objects connected to IBOutlet on dealloc method.
If the object connected another IBOutlet like the IBOutlet, it should be released once more to be dealloc.

Resources