Call methods from Swift initializer
declare it as an implicitly unwrapped optional
class MyClass : NSObject {
var myProperty: String!
init() {
super.init()
self.setupMyProperty()
}
func setupMyProperty() {
self.myProperty = "x"
}
}
page 499 of "The Swift Programming Language" manual
Use Function in Initializer - Swift?
I think it is not the greatest solution but still it is working.
class A {
var variable : Int
init() {
self.variable = A.assign(1)
}
private class func assign(y : Int) -> Int {
return y
}
}
How to call Swift initializer methods with multiple param in Objective-C
To be accessible and usable in Objective-C, a Swift class must be a
descendant of an Objective-C class or it must be marked @objc.
And also this answer.
This apple doc will also help you understand.
So the options for you is to either inherit the class of yours from some Objective C class (In this case compiler adds @objc
) or add @objc
yourself to your class.
You also need to add to your Objective C class-
#import "<#ProjectName#>-Swift.h"
Real solution to this specific question
Please look at this question, you will get your solution yourself. :)
That question says that optional parameters
can't be exposed from Swift to Objective C as all parmeters become _Nonnull
.
So I think you will need to create another initializer without optionals and default parameters.
Swift: why I can't call method from override init?
There are two competing initialization safety checks that are causing your problem.
Safety check 1
A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.
and
Safety check 4
An initializer cannot call any instance methods, read the values of any instance properties, or refer to self as a value until after the first phase of initialization is complete.
Here is how it works.
override init() {
super.init() // Fails safety check 1: uuid is not initialized.
uuid = createUUID()
}
conversely,
override init() {
uuid = createUUID() // Fails safety check 4: cannot call an instance method before initialization is complete.
super.init()
}
Thanks to @Ruben in his answer
How to call a class method in a convenience initializer in Swift
Instead of creating a class function for figuring out the id, create init functions instead. Since you already have to create one of these functions per subclass, you're not really losing anything. The subclasses init function then calls the super's init with the id name.
Here's an example, I changed some of the properties of your group just for the sake of making the example simple to illustrate the concept.
public class BaseAPIObject {
var objData: [String:String]
required public init(_ data: [String: String]) {
println("Data: \(data)")
self.objData = data
}
public convenience init(id: String, idFieldName: String) {
let data = [idFieldName: id]
self.init(data)
}
}
And then in your subclass, just conceptually something like this:
public class GroupObject: BaseAPIObject {
public convenience init (id: String) {
self.init(id: id, idFieldName: "group")
}
}
let go = GroupObject(id: "foo")
println(go.objData["group"]!) //prints "foo"
Swift: Call self method inside init
No, it's not a defect, simply self
cannot be referenced in an initializer until all stored properties have been initialized, and a super class initializer has been invoked (if any).
In your case it seems legit to do the initializations in a method, and call that from the initializer, but unfortunately it doesn't work.
Possible solutions:
- make the properties optional or implicitly unwrapped (discouraged, unless you really need them optionals)
initialize the properties with fake values before calling
reset
:init() {
self.a = 0
self.b = 0
self.c = 0
self.d = 0
reset()
}or
var a = 0
var b = 0
var c = 0
var d = 0
init() {
reset()
}
call a method from another class with required init coder
Looks like you're trying to update tab bar controller from one of tabs.
You can get reference to current tab bar controller (if there's one that's presenting this particular view controller) from your second controller using tabBarController
variable, try this:
(tabBarController as? MyTabBarCtrl)?.changeFloatingButtonColor()
Initialising member to class function causes 'self' used in method call error
It might be better to not use a Bool
, but rather a nested Enum
, which is also more extendible if you wanna add some other modes of haptic feedback later on.
I have a generalized solution for a generalized problem of your question. So either you do:
public class FunctionOwner {
private let mode: Mode
public init(`do` mode: Mode = .default) {
self.mode = mode
}
}
public extension FunctionOwner {
enum Mode {
case foo, bar
}
func fooOrBar() {
switch mode {
case .foo: foo()
case .bar: bar()
}
}
}
private extension FunctionOwner {
func foo() {
print("doing foo")
}
func bar() {
print("doing bar")
}
}
public extension FunctionOwner.Mode {
static var `default`: FunctionOwner.Mode {
return .foo
}
}
// USAGE
FunctionOwner(do: .bar).fooOrBar() // prints "doing foo"
FunctionOwner(do: .foo).fooOrBar() // prints "doing bar"
Or if you for some reason do want to keep the stored Mode
, you can do this (might be relevant for your actual question on how you do a workaround of referencing self
in the init.):
public class FunctionOwner {
private let _function: (FunctionOwner) -> Void
public init(`do` mode: Mode = .default) {
_function = { functionOwner in
switch mode {
case .foo: functionOwner.foo()
case .bar: functionOwner.bar()
}
}
}
}
public extension FunctionOwner {
enum Mode {
case foo, bar
}
func fooOrBar() {
_function(self)
}
}
// The rest of the code is the same as the example above
Related Topics
Swiftui: Detect Finger Position on MAC Trackpad
Forcing Nspersistentcontainer Change Core Data
Realitykit - Set Text Programmatically of an Entity of Reality Composer
One-Way Platform Collisions in Sprite Kit
How to Save Cgimage to Data in Swift
Uiimage Created from Mtkview Results in Color/Opacity Differences
Difference Between Switch Cases "@Unknown Default" and "Default" in Swift 5
Combining Two Conditions in Nspredicate
Swift Check Type Against a Generic Type
How to Set Inputview for Textfield in Swiftui
How to Get the Download Progress with the New Try Await Urlsession.Shared.Download(...)
Case Insensitive Dictionary in Swift
Swift 4.2+ Seeding a Random Number Generator
Xcode 8 Swift Update with Error "Use Legacy Swift Language Version"