What is better in this case: extension or function? [closed] - ios

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 months ago.
Improve this question
I have a ViewController where there's a logic for the "known" and "unknown" location.
At a high level it looks like this:
class MyViewController {
private var myVar: CLLocationCoordinate2D? // is updated somewhere
private var myFunc1() {
let someCond = myVar == nil // "isLocationUnknown" logic
}
private var myFunc2() {
guard let myVar == nil else { return } // "isLocationUnknown" logic
}
}
Now there's a requirement to handle the "invalid location" case.
Which means in addition to the nullability check, the CLLocationCoordinate2D check should be performed.
And I can't decide what is better ( as I don't know where to learn about Swift implementation details except of reading the sources :) ) :
Approach #1:
private func isLocationUnknown(_ location: CLLocationCoordinate2D?) -> Bool {
guard let location = location else {
return true
}
return !CLLocationCoordinate2DIsValid(location)
}
Approach #2:
private extension Optional where Wrapped == CLLocationCoordinate2D {
var isUnknown: Bool {
guard let self = self else {
return true
}
return !CLLocationCoordinate2DIsValid(self)
}
}
The criterias of comparison:
semantics: I guess #2 is more "swifty"/expressive etc
compilation time: can there be any difference (at scale)?
run-time performance: can there be any difference (at scale)?
I believe in this particular case all criterias are not important, but if this enum would be public, and called e.g. many times per second, or within multiple places in the codebase, then I'd like to be more confident when making the decision.

A class and func are reference types and stored on the heap and is therefore slower to access. Since the type Optional is an enum it is stored on the stack and will be quicker to access. But in this case it would probably not be a noticeable difference. Do which ever you feel is right.
If you want to read about memory management, here's a good article:
https://manasaprema04.medium.com/memory-management-in-swift-heap-stack-arc-6713ca8b70e1m
And here is a question about stack vs. heap memory:
Swift stack and heap understanding
EDIT:
Another thought is that your first approach takes CLLocationCoordinate2D as a parameter which creates a new copy of CLLocationCoordinate2D. So the space complexity is probably larger as well. But if that's the case, minuscule.

Related

Doubts about Swift initializers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last year.
Improve this question
I know this sounds like a silly question for all of you but I wanted to have more clarity on the differences of using init() or not in a structure
I meant that whether I use init() or not the parameters are still required. That's why I was wondering the difference of using init() or simple variables.
1^ Example without init()
struct ProductsImageView: View {
var image: String
var title: String
var time: Int
var isAllInOne: Bool = false
var body: some View {
}
}
2^ Example with init()
struct ProductsImageView: View {
var image: String
var title: String
var time: Int
var isAllInOne: Bool
init(image: String, title: String, time: Int, isAllInOne: Bool = false) {
self.image = image
self.title = title
self.time = time
self.isAllInOne = isAllInOne
}
var body: some View {
}
}
In both cases the various parameters will still be required when we call a structure in the code
ProductsImageView(image: "slider3", title: "Lorem", time: 60, isAllInOne: true)
Now I wanted to know when is it right to use init() and when not?
What are the differences?
Excuse me again for the stupid question but I prefer to have clear what I learn often I have some doubts and I ask you
If you don't write an init in the struct declaration, Swift will synthesize one for you. The init you wrote in example 2 is exactly the same as what Swift synthesizes in example 1.
However, the visibility of the synthesized init is always internal, even if the struct is public. So when you're creating a public struct and you want its init to be visible in other modules, you must write out its public init explicitly.

Best Approach to Refresh a Class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Simply i want to know what is the Best Approach to refresh a class.Like when same class is used from diff-diff section of application where we pass some data to that class ,I can do it by simply taking a global variable and change it's value from other class's But i want to know some another approach which is best suitable for this kind of Things.
The best way to handle this kind of structure, where the class needs to be effectively shared between other MVCs, is to make the class a singleton. This means that only one instance of a class is ever used. That way if one MVC changes the class you don't need to sync the change because every MVC uses the same instance.
To make a class a singleton you do the following
Create a static var which is an instance of the class
Make the init function private so no other class can initialise it
Eg
class Singleton {
static var shared = Singleton()
var info = "singleton info variable"
private init() {}
func doSomething() {}
}
To access the class you do the following
Singleton.shared.doSomething()
or
let singletonInfo = Singleton.shared.info
You have two options:
(Simplified) - Either you create a new instance and pass it on:
class MyClass {
let name: String
init(name: String) { self.name = name }
}
class MyViewController: UIViewController {
let myClass = MyClass(name: "Hello World")
func actionThatCausesSegue() {
let copyOfMyClass = MyClass(name: self.myClass.name)
self.performSegueWithIdentifier(identifier: "MySegue", sender: copyOfMyClass)
}
}
Or you can use structs:
struct MyStruct {
let name: String
init(name: String) { self.name = name }
}
class MyViewController: UIViewController {
let myStruct = MyStruct(name: "Hello World")
func actionThatCausesSegue() {
// structs are always copied when passed around.
self.performSegueWithIdentifier(identifier: "MySegue", sender: self.myStruct)
}
}
Structs are always copied, when you pass them around. Here's the explanation from the Swift Programming Language Guide by Apple:
Structures and Enumerations Are Value Types
A value type is a type whose value is copied when it is assigned to a
variable or constant, or when it is passed to a function.
You’ve actually been using value types extensively throughout the
previous chapters. In fact, all of the basic types in Swift—integers,
floating-point numbers, Booleans, strings, arrays and dictionaries—are
value types, and are implemented as structures behind the scenes.
All structures and enumerations are value types in Swift.
You can read more about the differences here.
It depends on the situation, but I sometimes do this for views in iOS. For example when the data model changes you want the view to update, so I implement a method in the controller called configureThingyViewWithThingy which takes the new 'thingy' and updates the view. Then whatever mechanism you're using to monitor data model changes (KVO, notifications, etc.) will call this method to reconfigure the view with the new data.

When do I want to use static, final, private in swift 2.2? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I kind of know when to use those different keywords, but can someone clarify for me when exactly do I want to use them, and how do they affect my apps during runtime?
static
You use a static method or property when you need some data without allocating new object, the most common use of static could be the singleton design pattern or when you have some helper class.
So for example in a function you can call:
let temp = Helper.staticMethod();
where
class Helper {
private let test1234 = false
private func privateMethod() {
}
private static func privateStaticMethod() -> Int {
return 0
}
static func staticMethod() -> Int {
self.privateMethod() // Error
self.test1234 // Error
self.test1234 // Error
Helper.privateStaticMethod() // OK
return 0
}
}
from staticMethod you can't have the access to NOT static method or property of the class Helper
final
It should be best practice declare all classes final and remove it just if you have to subclass them. Final provides you a compile time error if you try to subclass a final class and so this can help you to have a clean architecture without risking to create messy code and it help the readability of the code as well.
final class FinalClass {
}
class Sub1: FinalClass {
} //Error
class Base {
}
class SubBase: Base {
} //OK
private
A private class / property is not visible outside the scope.
It helps you to have a good encapsulation in your architecture.
class A {
private let test = 1
let test2 = 1
}
let classA = A()
classA.test //Error
classA.test2 //OK
I suggest reading the Swift documentation for better explanations:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html

How to get index of an item in a array? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
What is the most efficient way to get the index of an item in array? In Objective-C we used to be able to do:
[arrayName indexOfObject:myObject]
in Swift, I know we can do the following.
index =arrayName.indexOf({$0 === myObject})
is this the cleanest and most efficient way to do it?
As Oliver pointed out, you can use
let index = array.indexOf(myObject)
However, this will only work if your object conforms to the Equatable protocol, to conform to it, you have to implement the == function, like this:
class MyClass {
}
extension MyClass: Equatable { }
func ==(lhs: MyClass, rhs: MyClass) -> Bool {
return lhs === rhs // === returns true when both references point to the same object
}
If your class inherits from NSObject and your comparison is something other than just comparing pointers, you'll have to override isEqual: as well
override func isEqual(object: AnyObject?) -> Bool {
guard let obj = object as? MyClass else { return false }
return self == obj
}
You can use:
let index = array.indexOf(myObject)
You don't need to use the closure as indexOf accepts the element itself as an argument
Bear in mind that index is optional though

Expected declaration error (while loop) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 6 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I am in an iOS course and came across this error while making my app:
import Foundation
import UIKit
class RootsCateogry1: ViewController {
#IBOutlet weak var roots1Label: UILabel!
var rootsWeek1 = ["acro", "micro"]
var rootsWeek1Meaning = ["Air", "Small"]
var roots1Show = []
var temp = rootsWeek1.count // error here
var p = 0
var i = 0
while(i<temp){ // error here
roots1Show.append(rootsWeek1temp)
temp++
}
// ...
}
Screenshot
temp is a computed property, not a compile-time constant. You either need to override its getter or place it in your init or viewDidLoad:
var temp: Int {
return rootsWeek1.count
}
or:
override func viewDidLoad() {
super.viewDidLoad()
var temp = rootsWeek1.count
}
Your while loop must go in a function, it cannot exist at the class level. Consider moving that to your viewDidLoad as well. You are also not declaring a variable named rootsWeek1temp before adding it to roots1Show, so the compiler won't know what to append to the array if the object does not exist.

Resources