teyso teyso - 3 months ago 18
Swift Question

Swift button error on iOS app but not in playground

I am trying to learn swift to make free educational app for my country.

I know only the basics of programming and swift, but I am trying to understand iOS development.

I think I am having a problem with scope, but not sure what to do.

With

didMoveToView
being (the required) according to books I read, I can't compile and execute the code. So, when I run it in Xcode iOS App Project, my App crashes (even though it works in playground).




The code:



import UIKit
class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

class fooo {
static var bar = "hello world!"

@IBAction func hello_button(sender: AnyObject) {
print(fooo.bar)
}
}

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}


}





Below is the Crash log (Occurs on button touch):



2016-08-26 07:22:00.512 k[2074:37791] -[k.ViewController hello_button:]: unrecognized selector sent to instance 0x7aa2e670
2016-08-26 07:22:00.521 k[2074:37791] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[k.ViewController hello_button:]: unrecognized selector sent to instance 0x7aa2e670'
*** First throw call stack:
(
0 CoreFoundation 0x00200494 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01f17e02 objc_exception_throw + 50
2 CoreFoundation 0x0020a253 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0013f89d ___forwarding___ + 1037
4 CoreFoundation 0x0013f46e _CF_forwarding_prep_0 + 14
5 libobjc.A.dylib 0x01f2c0b5 -[NSObject performSelector:withObject:withObject:] + 84
6 UIKit 0x009f2e38 -[UIApplication sendAction:to:from:forEvent:] + 118
7 UIKit 0x009f2db7 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
8 UIKit 0x00b96f3b -[UIControl sendAction:to:forEvent:] + 79
9 UIKit 0x00b972d4 -[UIControl _sendActionsForEvents:withEvent:] + 433
10 UIKit 0x00b962c1 -[UIControl touchesEnded:withEvent:] + 714
11 UIKit 0x00a7352e -[UIWindow _sendTouchesForEvent:] + 1095
12 UIKit 0x00a745cc -[UIWindow sendEvent:] + 1159
13 UIKit 0x00a15be8 -[UIApplication sendEvent:] + 266
14 UIKit 0x009ea769 _UIApplicationHandleEventQueue + 7795
15 CoreFoundation 0x00112e5f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
16 CoreFoundation 0x00108aeb __CFRunLoopDoSources0 + 523
17 CoreFoundation 0x00107f08 __CFRunLoopRun + 1032
18 CoreFoundation 0x00107846 CFRunLoopRunSpecific + 470
19 CoreFoundation 0x0010765b CFRunLoopRunInMode + 123
20 GraphicsServices 0x04717664 GSEventRunModal + 192
21 GraphicsServices 0x047174a1 GSEventRun + 104
22 UIKit 0x009f0eb9 UIApplicationMain + 160
23 k 0x00012581 main + 145
24 libdyld.dylib 0x02935a25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Answer

You're right, the issue is scope (assuming you connected your button properly as others mentioned):


import UIKit

class ViewController: UIViewController {

    class fooo {
        var bar = "hello world!"
        func mSayBar() { print(self.bar)}
    }

    var foo = fooo()

    @IBAction func hello_button(sender: AnyObject) {
        foo.mSayBar()
    }

    override func viewDidLoad() {
        super.viewDidLoad()


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

viewDidLoad is it's own local scope--it doesn't extend any further than the end brace " } " After the first (millisecond?) everything declared in VDL is no longer alive; thus, it is best for initializing or calling, not declaring.

To declare global, just put everything in a new swift file, or put it outside ALL class scopes. Swift makes global scope easy (but be careful)

You said viewDidLoad is required, which is true, but only for setting up the program. Most of your logic / functions go outside of viewDidLoad