[swift-users] @objc and private methods
Svein Halvor Halvorsen
svein.h at lvor.halvorsen.cc
Sat Jul 23 15:21:59 CDT 2016
I usually mark my target-action methods like so:
private dynamic func didTapNext(sender: UIButton)
"dynamic" makes the compiler generate code for dynamic dispatch, that is
runtime message passing, like objc. The "private" part doesn't change that,
it just reduces clutter.
2016-07-22 15:18 GMT+02:00 Tod Cunningham via swift-users <
swift-users at swift.org>:
> What’s the best practice around using @objc on private methods? While
> they can be used together, should their use be avoided or embraced?
>
> Thanks,
> Tod
>
> From: Zhao Xin <owenzx at gmail.com>
> Date: Thursday, July 21, 2016 at 10:42 PM
> To: Josh Parmenter <jparmenter at vectorform.com>
> Cc: Tod Cunningham <tcunningham at vectorform.com>, "swift-users at swift.org" <
> swift-users at swift.org>
> Subject: Re: [swift-users] @objc and private methods
>
> My previous reply was not correct.
> I think @objc makes the function an Objective-C function, so the private
> is no longer making the function private in Swift way, but in Objective-C
> way. In C++, sub-class can call super-class's private method. What you
> have to do is to override the function.
>
> @objc makes the function available to Objective-C, but not only
> Objective-C. So the function works in both Objective-C and Swift. In Swift,
> the private is different from other languages, its scope is the surrounding
> file. That is why the override doesn't work if both classes are separated
> in different files.
>
> If the two classes are in the same file, below code also works.
>
>
> class Test {
>
>
>
> private func somefunc() {
>
>
>
> print( "hello 1" )
>
>
>
> }
>
>
>
> }
>
>
>
>
>
>
>
> class Test2: Test {
>
>
>
> override private func somefunc() {
>
>
>
> print( "hello 2" )
>
>
>
> }
>
>
>
> }
>
> So the only problem is with @objc and put the two classes into different
> files, you can't override the function as it is over-scoped in Swift.
> However, you can't use it in the same name either, as Objective-C will find
> the function names are conflicts.
>
> So the resolution is either to use it as it is, or to file a bug to
> eliminate using @objc and private together as there is no private access
> level in Objective-C.
>
> Zhaoxin
>
> On Fri, Jul 22, 2016 at 2:22 AM, Josh Parmenter <jparmenter at vectorform.com
> <mailto:jparmenter at vectorform.com>> wrote:
> Is this a bug? I think this is more a question of what is best practice.
> Best,
> Josh
>
> On Jul 21, 2016, at 10:48 AM, Zhao Xin via swift-users <
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>>> wrote:
>
> Then you should file a bug.
>
> Zhaoxin
>
> On Fri, Jul 22, 2016 at 1:03 AM, Tod Cunningham <
> tcunningham at vectorform.com<mailto:tcunningham at vectorform.com><mailto:
> tcunningham at vectorform.com<mailto:tcunningham at vectorform.com>>> wrote:
> If Test and Test2 are in separate files, swift doesn’t allow you to do the
> override as it “can’t see” the definition of the private method in Test.
>
>
> From: Zhao Xin <owenzx at gmail.com<mailto:owenzx at gmail.com><mailto:
> owenzx at gmail.com<mailto:owenzx at gmail.com>>>
> Date: Thursday, July 21, 2016 at 11:06 AM
> To: Tod Cunningham <tcunningham at vectorform.com<mailto:
> tcunningham at vectorform.com><mailto:tcunningham at vectorform.com<mailto:
> tcunningham at vectorform.com>>>
> Cc: "swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>>" <
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>>>
> Subject: Re: [swift-users] @objc and private methods
>
> I think @objc makes the function an Objective-C function, so the private
> is no longer making the function private in Swift way, but in Objective-C
> way. In C++, sub-class can call super-class's private method. What you
> have to do is to override the function.
>
>
> class Test {
>
> @objc private func somefunc() {
>
> print( "hello 1" )
>
> }
>
> }
>
>
>
> class Test2: Test {
>
> @objc override private func somefunc() {
>
> print( "hello 2" )
>
> }
>
> }
>
>
>
> Zhaoxin
>
>
>
>
> On Thu, Jul 21, 2016 at 10:25 PM, Tod Cunningham via swift-users <
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>>>> wrote:
> I wanted to get thoughts on the use of @objc and private methods. Should
> this usage be avoided or leveraged?
>
> I have seen some code where things like UIButton and Gesture recognizer
> handlers are defined as being private. I would have thought this would
> result in a compiler error given objective-c doesn’t support private
> accessors. However, it compiles and works as expected (kind of).
>
> One plus for defining the handlers as private is they aren’t visible to
> swift outside of the file they are defined in. The problem is you can run
> into some issues with inheritance if you define the same handler in a
> derived class. Take the following simple example:
>
> class Test {
> @objc private func somefunc() {
> print( "hello 1" )
> }
> }
>
> -- in another file –
>
> class Test2: Test {
> @objc private func somefunc() {
> print( "hello 2" )
> }
> }
>
> This will result in the following compiler error:
>
> Method 'somefunc()' with Objective-C selector 'somefunc' conflicts with
> method 'somefunc()' from superclass 'Test' with the same Objective-C
> selector
>
> That error makes sense in an Objective-C context as Test2 has two
> different methods defined with the same objective-c selector (somefunc).
> Swift can tell them apart as they are private to each class, but Obj-C
> can’t tell them apart as they have the same selector thus the error.
>
> One workaround would be to give the method a different Objective-C names
> such as @objc(test2_somefunc); however, that could really lead to some
> unexpected results depending on what selector is used to call somefunc.
> Test2 would need to “register” a different selector for somefunc then Test
> does for whatever is calling it on the Objective-C side (yuck!).
>
> This can of course be solved by not making the method private which allows
> Test2 to explicitly override somefunc.
>
> class Test {
> @objc func somefunc() {
> print( "hello 1" )
> }
> }
>
> -- in another file –
>
> class Test2: Test {
> @objc override func somefunc() {
> print( "hello 2" )
> }
> }
>
> I would say that when declaring @objc methods they shouldn’t be private
> and should have the same (public/internal) access method as their
> containing class. What’s your thoughts? Why does swift allow a method to
> be declared as both @objc and private?
>
> Thanks,
>
>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>>>
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org<mailto:swift-users at swift.org><mailto:
> swift-users at swift.org<mailto:swift-users at swift.org>>
> https://lists.swift.org/mailman/listinfo/swift-users
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160723/d5d46b7c/attachment.html>
More information about the swift-users
mailing list