@objc redundancy when having @objcMembers private dynamic var?
The problem is that while @objMembers
exposes your members to Objective-C, private
hides them again. Thus, to undo that hiding, you have to say @objc
explicitly.
To see that this is true, try the following test:
@objcMembers class MyObject: NSObject {
func f() {
print("howdy")
}
}
let c = MyObject()
c.perform(Selector("f"))
That works. But this crashes:
@objcMembers class MyObject: NSObject {
private func f() {
print("howdy")
}
}
let c = MyObject()
c.perform(Selector("f"))
To fix the crash without taking away the private
, we have to expose f
to Objective-C explicitly:
@objcMembers class MyObject: NSObject {
@objc private func f() {
print("howdy")
}
}
let c = MyObject()
c.perform(Selector("f"))
The only interesting thing about your particular case is that the compiler noticed the problem, instead of letting you just crash as in the second example above. That's because of the dynamic
marking, which makes no sense unless we are exposed to Objective-C.
Invoke Swift closure in Objective-C
Add to the function @objc modifier:
@objcMember
class User:NSObject {
@objc public func isReady(isTrue: Bool) -> Bool {
return true
}
}
And add public modifier to the function to allow access from other modules (swift code builds as module and ObjC code should export it and access via open interfaces).
Objective-C array of structs
Unfortunately, Objective C with Automatic Reference Counting (ARC) enabled does not allow for objects inside C structs. Objc also only allows objects inside NSArrays (the loose equivalent of vectors).
The first step of the solution is to create a class instead of a struct:
// Foo.h
#import <Foundation/Foundation.h>
@interface Foo : NSObject
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSArray *books;
// no need to keep the number of items in an NSArray as a separate variable,
// NSArray does that for you.
- (id)initWithTitle:(NSString *)title books:(NSArray *)books;
@end
// Foo.m
#import "Foo.h"
@implementation Foo
@synthesize title;
@synthesize books;
- (id)initWithTitle:(NSString *)title books:(NSArray *)books
{
if (self = [super init]) {
self.title = title;
self.books = books;
}
return self;
}
@end
Note that all object types are pointers. This is because all object in objc are heap allocated, so you can't object types that aren't pointers. Also note that the type NSArray
isn't parameterized. That's because objc doesn't have a concept of templates of generics, so the contents of the array could be any object. This usually isn't a problem, but occasionally a type error won't be caught at compile time.
To keep an array of these Foo
objects is simple. You could just make a C array of them like Foo *bar[50];
, but I don't think that works with ARC, and it definitely isn't the right way to do it in objective c. The right way is just to use another NSArray: NSArray *bar = [[NSArray alloc] init];
, or with objc2.0 syntax: NSArray *bar = @[];
Some notes that might help you
@property
and @synthesize
are shortcuts for making an instance variable and accessor methods for if. You need accessor methods if you want to access an instance variable from outside the class (or rather, the implementation file). The strong
flag tells the reference counter that this is a strong reference, like shared_ptr from the c++ boost libraries. I have no idea what nonatomic
does, but I'm told you need it.
The method initWithTitle:books:
is like a constructor, except that objc doesn't have a notion of constructors. The implementation calls the superclass's constructor with self = [super init]
(pretend that self is a c++ reference to the object). Constructors can return nil, so that's why you need the if block.
The line self.title = title;
is technically shorthand for [self setTitle:title];
, which uses a method autogenerated by @property
and @synthesize
.
Related Topics
Swift: Lazily Encapsulating Chains of Map, Filter, Flatmap
Swift and Objectmapper: Nsdate with Min Value
What Is the Markup Format for Documentation on the Parameters of a Block in Swift
How Does Let X Where X.Hassuffix("Pepper") Work
Com.Apple.Itunes Aedeterminepermissiontoautomatetarget Is Always Return -600
Changing Nav Bar Item Programmatically in Swift
How to Test an Optionset with a Switch Statement
Testing Protocol Conformance with Associated Types
Nspopover to Start in a Detached State
Not Getting Expected Delegate Calls When Trying to Restore In-App Purchases with Storekit
How to Give PDF Data a Filename for User to Save in Swift
A Codable Structure Contains a Protocol Property
How to Load the Photo Library into Uicollectionview? Swift
Using Structs (Bytes) with Swift - Struct to Nsdata and Nsdata to Struct