Inline If Statement Mutating Inout Parameter in a Void Return Closure, Weird Error (Error: Type 'Int1' Does Not Conform to Protocol 'Booleantype')

Inline if statement mutating inout parameter in a void return closure, weird error (Error: type 'Int1' does not conform to protocol 'BooleanType')

(Adding this thin answer to close the no-longer-relevant question)

The bug described in the question above is no longer present in Swift 2.2 (Xcode 7.3) nor in the Swift 3.0-dev at IBM Sandbox; so the issue seems to have been fixed in with the release of Swift 2.2.

Type 'Int' does not conform to protocol 'BooleanType'?

In Swift you can't implicitly substitute Int instead of Bool. This was done to prevent confusion and make code more readable.

So instead of this

let x = 10
if x { /* do something */ }

You have to write this:

let x = 10
if x != 0 { /* do something */ }

Also you can't pass an Optional instead of Bool to check if it's nil, as you would do in Objective-C. Use explicit comparison instead:

if myObject != nil { /* do something */ }

Type 'Int' does not conform to protocol 'BooleanType'

If you want to check, if your currentRow and indexPath are both 5 you can't use an if-statement like that. Change it to:

 if indexPath.row == currentRow?.row  && currentRow == 5 {

or:

 if indexPath.row == 5  && currentRow?.row == 5 {

If you want to check if indexPath is nil check if the indexPath is 0

if indexPath.row != 0 && currentRow?.row == 5 {

Why does this C++ closure produce different outputs?

std::function<void(void)> closureWrapper2()
{
int x = 10;
return [&x](){x += 1; std::cout << "Value in the closure: " << x << std::endl;};
}

It's undefined behaviour(a) to dereference a pointer to, or use a reference to, an object after that object no longer exists. That's what you're doing here. You capture a reference to x then attempt to use it after x has ceased to exist.

It's a local (automatic storage duration) variable inside closureWrapper2() so ceases to exist when that function exits.

That may appear to work without the cout line but that doesn't make it any less undefined. Putting the cout line is almost certainly modifying the stack where x was originally stored, changing the starting value.

You can get a similar effect with (in my environment):

void otherFn() { int abc = 97, def = 42, ghi = 9; std::cout << abc+def+ghi << '\n'; }

int main()
{
std::function<void(void)> func2 = closureWrapper2();
otherFn();
func2();
func2();
func2();
}

This indicates that the original value is definitely being overwritten by the abc variable in otherFn():

148
Value in the closure: 98
Value in the closure: 99
Value in the closure: 100

I had to try varying numbers of arguments as the stack frames for the closureWrapper2() and otherFn() are most likely different. Calling cout.operator<<() is likely to go through a number of stack levels to achieve its end so will be more likely to overwrite the original value.


(a) This is the solution to your problem, of course: don't do undefined behaviour :-)

Update to Xcode 12: Cannot convert value of type 'DataRequest' to closure result type 'Void'

I found the answer for that on Github.

https://github.com/mxcl/PromiseKit/issues/1165

I shouldn't be trying to return anything from the closure passed to Promise.init.
Weird how that was working in previous versions of Xcode.

To fix that I have to replace the return in front of Alamofire.request... with _ =

The function now looks like this:

    func fetchArticlesFromApi (API: String) -> Promise<[Article]> {
return Promise<[Article]> { seal in
_ = AF.request(API).validate().responseString(completionHandler: {
response in
switch (response.result) {
case .success(let responseString1):
//Do something
case .failure(let error):
print (error)
seal.reject(error)
}
})
}
}

return' cannot transfer control out of a defer statement

  1. Returning more than one value is not allowed, regardless of whether you try to do that in a defer statement or not.

  2. Whatever you do to mutate a return value in a defer statement, that's not accessible via a return. It happens afterward.

func someone() -> String {
var `return` = "Hello"

defer {
`return` += "World"
}

return `return`
}

someone() // Hello

Weird crash when calling closure with generic parameters in Swift 3

I have added NSObject to associatedtype and now it doesn't crash.
It doesn't answer your question, but maybe this temp solution will help you

protocol CrashProtocol {
associatedtype T: NSObject

static func tryCrash(_ dummyInt: Int,
with closure: ((T) -> Void))
}

class Crash<M:NSObject>: CrashProtocol {
typealias T = M

class func tryCrash(_ dummyInt: Int,
with closure: ((M) -> Void)) {
print("Crash tryCrash")
}
}


Related Topics



Leave a reply



Submit