Swift Regex Deep Dive
iOS MacOur introductory guide to Swift Regex. Learn regular expressions in Swift including RegexBuilder examples and strongly-typed captures.
Today’s topic was suggested by Paul Bruneau – thanks!
In case you’ve lost count, we have three places we can declare instance variables in modern Objective-C:
The first is in the class interface, as it always has been:
@interface BNRThingie : NSObject {
NSString *_thingie1;
int _thingie2;
}
@end // BNRThingie
The second is in the class extension:
@interface BNRThingie () {
NSString *_extensionThingie1;
int _extensionThingie2;
}
@end // extension
The third is at the start of the class implementation:
@implementation BNRThingie {
NSString *_implementationThingie1;
int _implementationThingie2;
}
...
@end // BNRThingie
No matter where you declared your instance variables, you can access them in the class:
- (NSString *) description {
NSString *desc = [NSString stringWithFormat: @"<%@:%p %@ %d %@ %d %@ %d>",
[self class], self,
_thingie1, _thingie2,
_extensionThingie1, _extensionThingie2,
_implementationThingie1, _implementationThingie2];
return desc;
} // description
This brings up the question: “Where should I put my instance variables?” For the most part, you’ll probably make @propertie
s and use @synthesize
to create the backing ivar. (You can read more about that at A Motivaton for ivar decorations) The development version of clang
supports auto-synthesis of instance variables, so you won’t even have to do @synthesize
.
If you have to support older compilers (such as gcc
) you’ll need to put the instance variables in the @interface
. Similarly, older versions of Xcode don’t have the debugger support for ivars declared anywhere else but the @interface
. If you want to see your ivars in Xcode’s debugger panels, you’d need to put ivars in the @interface
. Luckily newer Xcodes don’t have this limitation.
If you have public instance variables, part of your public interface, they’d go into the @interface
as well. This probably isn’t a wise design idea, but it might be something you have to do.
If your instance variables are private, purely implementation details, put them into the implementation. It still feels weird to put them there, but I’ve been doing Cocoa long enough that I have some ingrained habits to break:
@implementation SomeThing {
SomeThingTrackingMode _trackingMode;
CGPoint _anchorPoint, _dragPoint;
}
- (id) initWithPancake: (void *) waffle {
...
You can also put them into the class extension if it feels better to you to consolidate the meta / declaratory stuff in one place.
One thing that’s kind of cool is you can declare instance variables in a class extension, then include that class extension (via another header file) into a subclass implementation. You’ll need to make the class extension instance variables @protected
or @public
so your subclasses can have access to them. This allows you to keep your public header very clean (no instance variables), and have a secondary header with the class extension that’s used by test code and/or subclasses.
Another thing that’s kind of cool is you can put your IBOutlet
decorations on instance variables declared in a class extension or in the implementation, as well as decorations on @properties
that live in class extensions. Interface Builder will pick up on the outletitude and let you make connections, but also keep them out of the public header file if they’re just implementation details. They’d look something like this:
@interface SomeThing () {
IBOutlet NSView *_extensionView;
}
@property (strong) IBOutlet NSView *extensionProperty;
@end // extension
@implementation SomeThing {
IBOutlet NSView *_implementationView;
}
And would be available in Xcode like this:
Here are my rules of thumb for ivar location:
For older compilers or older Xcodes that don’t fully support non-interface ivars, I put them into the @interface
If it’s a public ivar, into @interface
it goes (I haven’t actually had to use this rule yet)
If it’s a private implementation detail, I put it into the @implementation. Sometimes I put them in the class extension. I haven’t totally Searched My Feelings on this one.
If it’s something to be exposed to subclasses or to tests, it goes into a class extension in a separate header file.
Fascinated by the ins and outs of Objective-C? The Advanced Mac Bootcamp covers the language in extensive detail.
Our introductory guide to Swift Regex. Learn regular expressions in Swift including RegexBuilder examples and strongly-typed captures.
The Combine framework in Swift is a powerful declarative API for the asynchronous processing of values over time. It takes full advantage of Swift...
SwiftUI has changed a great many things about how developers create applications for iOS, and not just in the way we lay out our...