why is this Swift initializer legal
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
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
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
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
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
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
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
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
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
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
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
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
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
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