David
David

Reputation: 1172

EXC_BAD_ACCESS using self.performSelector

This is a simple academic not real code.

I want to run print method using performSelector function. But If I run this code in playground, throws an exception:

EXC_BAD_ACCESS (code=EXC_I386_GPFLT).

Code:

//: Playground - noun: a place where people can play

import UIKit

@objc(Foo)
class Foo: NSObject {

    func timer() {
        self.performSelector( #selector(Foo.print))
    }

    @objc func print() {
        NSLog("print")
    }
}

let instance = Foo()
instance.timer()     // <-- EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

Where is the problem?

Upvotes: 4

Views: 1243

Answers (2)

JAL
JAL

Reputation: 42449

Here's a solution which does not require a change in function signature:

class Foo {

    func timer() {
        (self as AnyObject).performSelector(#selector(Foo.print))
    }

    @objc func print() {
        NSLog("print")
    }
}

let instance = Foo()
instance.timer()

Might have to do with Objective-C API bridging, still investigating...

Upvotes: 3

OOPer
OOPer

Reputation: 47876

Try changing your Foo.print() to something like this:

    @objc func print() -> AnyObject? {
        NSLog("print")
        return nil
    }

I believe the code runs in the Playground too.

performSelectors return type is not Void.

- performSelector:

func performSelector(_ aSelector: Selector) -> Unmanaged<AnyObject>!

So, Playground tries to get the result value to display. Which in fact is not returned.

Upvotes: 3

Related Questions