why is this Swift initializer legal

2015-06-06 Thread Roland King


public class RDKBLEService : NSObject
{
let peripheral : CBPeripheral

public init( peripheral: CBPeripheral )
{
self.peripheral = peripheral
}
}

It’s a designated initialiser, there’s a superclass (NSObject) but the 
initialiser doesn’t call a designated initialiser of the superclass. According 
to the rules I was just re-re-re-reading about Swift initialisation, it’s 
required to call a superclass designated initialiser from your derived class. I 
was looking to see if I could find an exception to the rule which this fell 
under but can’t. 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Forwarding messages to another class

2015-06-06 Thread Cosmo
Sorry. I was inaccurate in my language. I’m actually calling these methods on 
the superclass, not on instances of it.

 On Jun 6, 2015, at 4:58 PM, Graham Cox graham@bigpond.com wrote:
 
 
 On 7 Jun 2015, at 8:47 am, Cosmo minonom...@gmail.com wrote:
 
 I should have explained that I’m calling these methods on instances of the 
 superclass, not the subclass, so inheritance doesn’t work.
 
 
 But you have written class methods, so instances doesn’t come into it. Seems 
 possible that there’s a fundamental misunderstanding involved here.
 
 What you’ve described (a base class that provides a generic interface, with 
 specific implementations in subclasses) is eminently doable - in fact largely 
 the entire point of object-oriented programming - but perhaps you should 
 simply be doing this using straightforward instance methods, not class 
 methods?
 
 —Graham
 
 


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Forwarding messages to another class

2015-06-06 Thread Kyle Sluder
On Jun 6, 2015, at 2:35 PM, Cosmo minonom...@gmail.com wrote:
 
 I’m trying to send messages from a class to one of its subclasses. I have a 
 method that returns the class I want to forward to. If I use it in the 
 following manner, it works:
 
 + (void)logout
 {
// subclasses handle it
[[self classToUseForBackend] logout];
 }
 
 By setting breakpoints in this method and the subclass I can see that the 
 message goes where i expect.
 
 If I use it in the following manner, the message is not forwarded to the 
 subclass with the identical signature. It ends up being re-sent to the 
 superclass method (i.e. where I’m calling it here) and I get an infinite loop.
 
 + (NSString *)errorMessageForCode:(NSInteger)errorCode
 {
// subclasses handle it
NSString *msg = [[self classToUseForBackend]

Objective-C uses purely dynamic dispatch. `self` always refers to the instance 
the message is being sent to, regardless of what class owns the method 
implementation that happens to be sending the message. So [self 
classToUseForBackend] will *always* invoke the most-specific 
(“most-overridden”) implementation of that method.

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Forwarding messages to another class

2015-06-06 Thread Cosmo
Thanks for the response.

 On Jun 6, 2015, at 3:15 PM, Quincey Morris 
 quinceymor...@rivergatesoftware.com wrote:
 
 On Jun 6, 2015, at 14:35 , Cosmo minonom...@gmail.com wrote:
 
 Can somebody explain to me why I’m getting this different behavior. Is there 
 anything I can do to achieve my goal?
 
 The most likely immediate reason is that the class returned by '[self 
 classToUseForBackend]’ doesn’t actually implement a method called 
 ‘errorMessageForCode:’. If you think it does, check the spelling and 
 capitalization of the method name in the subclass.
 
 However, the code fragments you show here don’t make any sense. Class methods 
 in Obj-C (methods with a ‘+’) have inheritance like instance methods. So, if 
 a subclass implements (say) ‘logout’, execution is never going to reach the 
 superclass implementation. If a subclass *doesn’t* implement (say) 
 ‘errorMessageForCode:’, you’re going to get an infinite loop.
 

 The first code example I included definitely works. And I copied and pasted 
the method signatures from the superclass to the subclass, so there should not 
have been any differences. (I did it a second time for that second example to 
make sure that wasn’t the source of the problem.)

 Furthermore, if the subclass method happens to call the ‘super’ method, then 
 you will again end up with an infinite loop.
 
 If your intention is to have a class hierarchy where the base class defines 
 methods that the subclass must implement — that is, where the base class has 
 abstract methods — there are two straightforward ways:
 
 1. Define the base class method but don’t do anything in it, except possibly 
 to cause an exception:
 
   + (void) logout {
   NSAssert (NO, @“Subclass responsibility”);
   }
 
 2. Use a protocol instead of a base class:
 
   @protocol BaseClassProtocol
   + (void) logout;
   @end
 
I should have explained that I’m calling these methods on instances of the 
superclass, not the subclass, so inheritance doesn’t work. I am trying create 
structures with a high-level object that my app knows about, which can call 
through to decoupled objects written for specific database backends. I suppose 
they don’t necessarily need to be subclasses, and that protocols might be a 
better solution.

In searching for an explanation before asking my question on this list I found 
a few discussions of message forwarding in Objective-C. I saw examples of 
forwarding messages with a return type and no parameters, and no return type 
with a single parameter. But none included anything about forwarding a message 
with both a return type and a parameter. I didn’t see anything saying this 
cannot be done, so I thought there might be somebody on this list who’d know 
more about that and could give me a definitive answer. For now, my totally 
baseless guess is that Objective-C does not support that combination.

In any event I realized that I could pass in a block and accomplish what I want 
successfully, so I can move on. But I will consider changing this to use 
protocols instead.




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Forwarding messages to another class

2015-06-06 Thread Graham Cox

 On 7 Jun 2015, at 8:47 am, Cosmo minonom...@gmail.com wrote:
 
 I should have explained that I’m calling these methods on instances of the 
 superclass, not the subclass, so inheritance doesn’t work.


But you have written class methods, so instances doesn’t come into it. Seems 
possible that there’s a fundamental misunderstanding involved here.

What you’ve described (a base class that provides a generic interface, with 
specific implementations in subclasses) is eminently doable - in fact largely 
the entire point of object-oriented programming - but perhaps you should simply 
be doing this using straightforward instance methods, not class methods?

—Graham



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: why is this Swift initializer legal

2015-06-06 Thread Roland King

 On 7 Jun 2015, at 02:18, Marco S Hyman m...@snafu.org wrote:
 
 public class RDKBLEService : NSObject
 {
  let peripheral : CBPeripheral
 
  public init( peripheral: CBPeripheral )
  {
  self.peripheral = peripheral
  }
 }
 
 Swift doesn’t think init in NSObject is a designated initializer.  Add
 “override” as you would with a designated initializer and you get an error
 stating “does not override a designated initializer from its superclass”.
 
 I do not know why.
 
 Marc

No that’s not correct I’m afraid. Swift does know init() in NSObject is a 
designated initializer. If I try to define a no-arg init() in my subclass then 
I get an error telling me I need to add the override keyword, which would be 
correct as I would then be trying to override NSObject’s designated initializer 
(hereafter abbreviated DI). The signature of my DI has an argument so it’s 
different so it’s not an override. It is however a DI and thus should by the 
very explicitly listed rules call a DI in the superclass

Oddly enough if I add any line after the self.peripheral = peripheral which 
uses self, anything, just a random thing like self.observationInfo (it was the 
first one under my cursor) then I get an error that I’m using self before 
calling a super.init call. 

Quincey may well be right and in the case of a class which has one single, 
no-arg, DI that DI is automagically added in by the compiler at the end of the 
method. I rather hope that’s not true, Swift is already replete with little 
rules and oddities you have to know about, if the rule is you call a DI, you 
should have to call one, the compiler shouldn’t be ‘just letting you get away 
with it’ in certain cases. 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Forwarding messages to another class

2015-06-06 Thread Cosmo
I’m trying to send messages from a class to one of its subclasses. I have a 
method that returns the class I want to forward to. If I use it in the 
following manner, it works:

+ (void)logout
{
// subclasses handle it
[[self classToUseForBackend] logout];
}

By setting breakpoints in this method and the subclass I can see that the 
message goes where i expect.

If I use it in the following manner, the message is not forwarded to the 
subclass with the identical signature. It ends up being re-sent to the 
superclass method (i.e. where I’m calling it here) and I get an infinite loop.

+ (NSString *)errorMessageForCode:(NSInteger)errorCode
{
// subclasses handle it
NSString *msg = [[self classToUseForBackend] errorMessageForCode:errorCode];

return msg;
}

Can somebody explain to me why I’m getting this different behavior. Is there 
anything I can do to achieve my goal?
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Forwarding messages to another class

2015-06-06 Thread Quincey Morris
On Jun 6, 2015, at 14:35 , Cosmo minonom...@gmail.com wrote:
 
 Can somebody explain to me why I’m getting this different behavior. Is there 
 anything I can do to achieve my goal?

The most likely immediate reason is that the class returned by '[self 
classToUseForBackend]’ doesn’t actually implement a method called 
‘errorMessageForCode:’. If you think it does, check the spelling and 
capitalization of the method name in the subclass.

However, the code fragments you show here don’t make any sense. Class methods 
in Obj-C (methods with a ‘+’) have inheritance like instance methods. So, if a 
subclass implements (say) ‘logout’, execution is never going to reach the 
superclass implementation. If a subclass *doesn’t* implement (say) 
‘errorMessageForCode:’, you’re going to get an infinite loop.

Furthermore, if the subclass method happens to call the ‘super’ method, then 
you will again end up with an infinite loop.

If your intention is to have a class hierarchy where the base class defines 
methods that the subclass must implement — that is, where the base class has 
abstract methods — there are two straightforward ways:

1. Define the base class method but don’t do anything in it, except possibly to 
cause an exception:

+ (void) logout {
NSAssert (NO, @“Subclass responsibility”);
}

2. Use a protocol instead of a base class:

@protocol BaseClassProtocol
+ (void) logout;
@end



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Forwarding messages to another class

2015-06-06 Thread Quincey Morris
On Jun 6, 2015, at 17:04 , Cosmo minonom...@gmail.com wrote:
 
 Sorry. I was inaccurate in my language. I’m actually calling these methods on 
 the superclass, not on instances of it.

What you’re really doing here is a combination of two standard Obj-C patterns:

1. Singleton pattern. You’re using the class objects (that is, the meta-objects 
that represent the classes themselves) as singleton objects — as the single 
object that implements certain behavior.

There’s nothing absolutely wrong with this, but it’s more usual to create a 
single instance of a class instead of implementing the behavior as class 
methods. There are a few drawbacks to using the class object, the most obvious 
one being that class objects can’t have @property-style properties.

2. Delegation pattern. In “decoupling” the secondary (subclass) objects from 
the primary (base class) object, clients of your class API are sending messages 
to one object, which then has another object do some or all of the work.

In your case, since the API of the primary object and the API of the delegate 
is the same (they respond to the same methods), perhaps it would be more 
accurate to call this a proxy pattern rather than a delegate pattern, but the 
idea is much the same.

Again, there’s nothing absolutely wrong with the way you’re trying to do this, 
but in modern Obj-C the best way is to write the API into a protocol, and to 
have the primary class adopt the protocol. As far as clients of the class are 
concerned, the “decoupled” objects are an implementation detail they don’t care 
about, so the method of delegation is an implementation detail, too. There’s no 
need, for example, for the secondary objects to be subclasses of the primary 
object. For simplicity, you can choose to just make the secondary objects 
conform to the same protocol.

I’d avoid calling this “forwarding”, because that term has a very specific 
meaning in Obj-C. There is in fact a formal method forwarding mechanism, but 
you’ve re-invented it informally.

In terms of what’s currently going wrong, you have all the information you need 
to debug this. You can set breakpoints, and you can examine the result of 
'[self classToUseForBackend]’ in the debugger, so you should be able to see 
what’s going on.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Using CFSTR() with const char * variable

2015-06-06 Thread Steve Christensen
In my prefix file that is used to build precompiled headers, I include the 
following after #import-ing all the framework headers. It replaces the standard 
definition with a version that doesn't insert quotes around an unquoted string 
literal.

#undef CFSTR//(cStr)
#ifdef __CONSTANT_CFSTRINGS__
#define CFSTR(cStr)  ((CFStringRef) 
__builtin___CFStringMakeConstantString(cStr))
#else
#define CFSTR(cStr)  __CFStringMakeConstantString(cStr)
#endif



 On Jun 5, 2015, at 8:02 PM, Carl Hoefs newsli...@autonomy.caltech.edu wrote:
 
 If I use CFSTR() in the following way:
CFStringRef mystr = CFSTR( This is a string );
 there is no problem.
 
 However, if I use a variable instead of “string” Xcode flags this as an error:
const char *mystring = This is a string;
CFStringRef mystr = CFSTR( mystring );
   ^   — Expected )
 
 In CFString.h, CFSTR is defined as:
#define CFSTR(cStr)  __CFStringMakeConstantString( cStr )
 
 Is it possible to use CFSTR() with a const char * variable?
 
 Xcode 6.3.2
 -Carl


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: why is this Swift initializer legal

2015-06-06 Thread Quincey Morris
On Jun 6, 2015, at 18:10 , Roland King r...@rols.org wrote:
 
 Quincey may well be right and in the case of a class which has one single, 
 no-arg, DI that DI is automagically added in by the compiler at the end of 
 the method.

After further thought, I’d say something stronger. In the scenario we’re 
talking about (the superclass has a single designated init, with no 
parameters), the subclass *must* call ‘super.init ()’. It’s the only 
possibility, and it’s absolutely required, so there’s no danger in the compiler 
doing it for you.

 I rather hope that’s not true, Swift is already replete with little rules and 
 oddities you have to know about

I thought about this too, but many of these little rules and oddities are cases 
where writing something yourself is as much a Forced Move as the 'super.init 
()’ above. It would be perfectly *logical* to make you write them yourself, so 
as to avoid “exceptional” syntax rules, but one of the annoying things about 
Obj-C is that we have to write lots and lots of stuff that the compiler already 
knows. Lots and lots and lots of stuff.

In this case, it’s harmless. If you write the super call, it’s fine. If you 
omit it, there’s no possible danger. (If you subsequently change the superclass 
in a way that makes it dangerous, you’ll start getting errors.)

It’s also useful, as well as harmless. There are plenty of real-life situations 
where you have class hierarchies that only have parameterless designated 
initializers. This convention allows you to leave them out all the calls to 
them. Plus, there’s a *default* parameterless designated initializer convention 
that may let you leave out all of the initializers completely. Again, since 
it’s safe, future-proof and convenient, I’d say better to have it than not.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: why is this Swift initializer legal

2015-06-06 Thread Roland King

 On 7 Jun 2015, at 10:01, Quincey Morris quinceymor...@rivergatesoftware.com 
 wrote:
 
 On Jun 6, 2015, at 18:10 , Roland King r...@rols.org mailto:r...@rols.org 
 wrote:
 
 Quincey may well be right and in the case of a class which has one single, 
 no-arg, DI that DI is automagically added in by the compiler at the end of 
 the method.
 
 After further thought, I’d say something stronger. In the scenario we’re 
 talking about (the superclass has a single designated init, with no 
 parameters), the subclass *must* call ‘super.init ()’. It’s the only 
 possibility, and it’s absolutely required, so there’s no danger in the 
 compiler doing it for you.
 
 I rather hope that’s not true, Swift is already replete with little rules 
 and oddities you have to know about
 
 I thought about this too, but many of these little rules and oddities are 
 cases where writing something yourself is as much a Forced Move as the 
 'super.init ()’ above. It would be perfectly *logical* to make you write them 
 yourself, so as to avoid “exceptional” syntax rules, but one of the annoying 
 things about Obj-C is that we have to write lots and lots of stuff that the 
 compiler already knows. Lots and lots and lots of stuff.
 
 In this case, it’s harmless. If you write the super call, it’s fine. If you 
 omit it, there’s no possible danger. (If you subsequently change the 
 superclass in a way that makes it dangerous, you’ll start getting errors.)
 
 It’s also useful, as well as harmless. There are plenty of real-life 
 situations where you have class hierarchies that only have parameterless 
 designated initializers. This convention allows you to leave them out all the 
 calls to them. Plus, there’s a *default* parameterless designated initializer 
 convention that may let you leave out all of the initializers completely. 
 Again, since it’s safe, future-proof and convenient, I’d say better to have 
 it than not.
 

Going to have to agree to disagree on this one. The rules about inherited 
initializers and cases you don’t need to write intializers at all make sense to 
me, even if I have to read them occasionally to remind myself. But if there’s a 
rule that a DI needs to call a superclass DI (if it has a superclass) then it 
should be like that in every class. I’d be happier if Xcode put up an error and 
offered to fix it by inserting the missing line, as it so often does, than just 
hiding it. If I could find a place it was documented in which cases the 
compiler does it for you I’d think ‘ugh’ but try to remember that rule too, I 
can’t find it documented anywhere, so I filed it. 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: why is this Swift initializer legal

2015-06-06 Thread Quincey Morris
On Jun 6, 2015, at 02:43 , Roland King r...@rols.org wrote:
 
 I was looking to see if I could find an exception to the rule which this fell 
 under but can’t.

It looks like this isn’t something that falls under those rules, but is rather 
one of the Swift compiler conveniences that writes boilerplate code for you: if 
you don’t write the super.init call, the compiler inserts it for you.

AFAICT from playing around in playgrounds, it only does this for a 
parameterless super.init, and it only does this when the superclass has no 
other designated initializers.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: why is this Swift initializer legal

2015-06-06 Thread Marco S Hyman
 public class RDKBLEService : NSObject
 {
   let peripheral : CBPeripheral
 
   public init( peripheral: CBPeripheral )
   {
   self.peripheral = peripheral
   }
 }

Swift doesn’t think init in NSObject is a designated initializer.  Add
“override” as you would with a designated initializer and you get an error
stating “does not override a designated initializer from its superclass”.

I do not know why.

Marc
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com