What Is the Swift Equivalent of Makeobjectsperformselector

What is the swift equivalent of makeObjectsPerformSelector?

Updated for Swift 2.0 (Xcode 7)

Use forEach:

self.view.subviews.forEach { subview in
subview.removeFromSuperview()
}

Or like this:

view.subviews.forEach { $0.removeFromSuperview() }

bridgeToObjectiveC and makeObjectsPerformSelector in Swift beta 5

The bridgeToObjectiveC and bridgeFromObjectiveC functions are not available in Xcode 6.0 beta 5. Instead, cast to/from the appropriate Foundation type when you need to use that type's API on a Swift object. For example:

var arr = ["One", "Two"]
(arr as NSArray).indexOfObject("One")

Apple has warned against (or explicitly made unavailable) using performSelector and related methods since the first Swift beta. Presumably any such API that were still available before beta 5 were unintentionally so.

As the question you cited notes, you can use map to call a function/method on every element of an array. You can also use filter, find or a for-in loop, or after casting to NSArray, one of the enumerateObjects methods. Note that many consider it bad style to use the functional-programming constructs (map, filter, reduce, find) for tasks that aren't "functional" -- that is, to run code that has side effects. So a for-in loop might be the cleanest way to do what you're after.

How can I execute the same function for all objects of a collection in Swift?

You can try

observers.forEach { $0.update(message: "updated") }

Remove all the subviews from a UIScrollView?

Let scrollView be an instance of UIScrollView.

In Objective-C, it's pretty easy. Just call makeObjectsPerformSelector:, like so:

Objective-C:

[scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

In Swift, you don't get that runtime access, so you have to actually handle the iteration yourself.

Swift:

A concise version, from here:

scrollview.subviews.map { $0.removeFromSuperview() }

A more descriptive way to do this (from here) assumes scrollview.subviews:

let subviews = self.scrollView.subviews
for subview in subviews{
subview.removeFromSuperview()
}

bridgeToObjectiveC not available on Swift Beta 5

Use as to cast to NSString for the same effect:

("string" as NSString).localizedCaseInsensitiveCompare("other string")

Or like this with optional chaining:

("string" as NSString?)?.localizedCaseInsensitiveCompare("other string")

How to update an array with WritableKeyPath in Swift 4.0

Mutating into a member of an array requires an l-value. Swift's mechanism for l-values is the subscript, so we can use that:

for i in people.indices {
people[i][keyPath: \Person.name] = updated
// or more simply, just:
// people[i].name = "updated"

// This even works too, but I can't see any reason why it would be desirable
// over the other 2 approaches:
// people[keyPath: \[Person].[i].name] = "update"
}

You could also use forEach, but I generally only recommend that over for in cases where you have an existing closure/function to pass in which has type (Index) -> Void:

// meh
people.indices.forEach {
people[$0][keyPath: \Person.name] = "updated"
}

Obj C and makeObjectsPerformSelector - am I overlooking something?

To bypass the problem of int to be a C type and not an object, use KVC (Key-Value Coding). If you call setValue:forKey: on a NSArray object, the method setValue:forKey: is call on each of the objects of the array. And with a bonus, KVC is managing all the primitive stuff.

[_stepper setValue:@0 forKey:@"value"];
[_fields setValue:@"0" forKey:@"text"];

bridgeToObjectiveC() not available for Array in Swift

Note that Swift has a 'find' function that you can use to see if an element is in an array or not:

find(array,element):C.Index?

It will return nil if the item is not found. You should probably use this instead of contains.

When to use forEach(_:) instead of for in?

There is no performance benefit offered by forEach. In fact, if you look at the source code, the forEach function actually simply performing for-in. For release builds, the performance overhead of this function over simply using for-in yourself is immaterial, though for debug builds, it results in an observable performance impact.

The main advantage of forEach is realized when you are doing functional programming, you can add it to a chain of functional calls, without having to save the prior result into a separate variable that you'd need if you used for-in syntax. So, instead of:

let objects = array.map { ... }
.filter { ... }

for object in objects {
...
}

You can instead stay within functional programming patterns:

array.map { ... }
.filter { ... }
.forEach { ... }

The result is functional code that is more concise with less syntactic noise.

FWIW, the documentation for Array, Dictionary, and Sequence all remind us of the limitations introduced by forEach, namely:

  1. You cannot use a break or continue statement to exit the current
    call of the body closure or skip subsequent calls.

  2. Using the return statement in the body closure will exit only from
    the current call to body, not from any outer scope, and won't skip
    subsequent calls.



Related Topics



Leave a reply



Submit