> On Feb 13, 2015, at 2:08 PM, Quincey Morris 
> <[email protected]> wrote:
> 
> It seems to me that the outcomes you’ve described are what would be expected, 
> except in a couple of details.
> 
> On Feb 13, 2015, at 12:17 , Mike Ellard 
> <[email protected] 
> <mailto:[email protected]>> wrote:
>> 
>> What I would expect:
>> 
>> A) Swift would not expose alloc or `new` at all.  There shouldn’t be a way 
>> to create objects without going through an initializer.
> 
> I don’t know why you included ‘new’ in here. It’s valid to use it as a 
> factory method in a subclass of NSObject, and I assume the behavior you’re 
> seeing comes from Swift treating it as a factory method because of its name. 
> As you showed, it doesn’t *not* go through an initializer. I don’t see how 
> Swift could disallow it.

Part of the problem with `new` is that it is a shorthand for alloc and init.  
This is fine in Objective-C, where every subclass of NSObject inherits a valid 
init method.  However, in Swift, initializers are not inherited if a subclass 
adds new, non-optional properties.  So a Swift class may not have a valid 
argumentless initializer.  If you hit a case like this, which is probably quite 
common, `new` will cause a runtime error. 

You can see the Playground that I just attached to Radar 19834469 for an 
example of this.  

>> B) If a class does override alloc (either in Swift in or a mixed Objective-C 
>> / Swift project), then initializing an object would call the overridden 
>> alloc method.  
> 
> This is the one that’s a bit puzzling. There are frameworks classes (such as 
> NSArray IIRC) that return a placeholder object from ‘alloc’ and do their 
> actual memory allocation in ‘init’, and creating such objects in Swift would 
> break (or would they?) if Swift used an object creation methodology that 
> didn’t do alloc/init in the Obj-C way.

I’m not saying that there shouldn’t be underlying alloc and `new` methods in 
the Objective-C classes.  Obviously, those have to be there.  However, not 
everything in Objective-C needs to be exposed in Swift.  For example, all of 
the performSelector variants are not exposed in Swift.  They’re still there in 
Objective-C, but Swift doesn’t give developers an easy way to use / misuse 
them.  The same thing could be done with alloc and `new`.  In Swift, they could 
be internal methods rather than public ones.

> 
> It’s possible that Swift alloc/inits Obj-C-style objects in the Obj-C-normal 
> way, but that alloc and init overrides don’t produce the same runtime class 
> structure as the corresponding Obj-C overrides.
> 
> I think your test needs to be a bit more intricate. What happens if you 
> subclass NSObject in Obj-C with an alloc override, then sub-subclass that in 
> Swift, also with an alloc override. Which, if any, allocs are invoked in that 
> case?
> 
> Similarly, what happens if you subclass NSObject in Swift with an alloc 
> override, then instantiate that class in Obj-C using the standard alloc/init 
> sequence? (You could sub-subclass in Obj-C for parallelism, if you wanted, 
> but I suspect the simpler test will suffice.)

The additional tests you’ve suggested are interesting.  They would provide 
interesting additional material for Radar 19830571, and perhaps a couple of new 
Radars as well. I will run them if I have a chance to do so.   

>> C) That in Swift, the NSObject alloc method would be “final” so that it 
>> couldn’t be overridden.  
> 
> As before, I’m not sure why you would want this. If Swift and Obj-C are to be 
> interoperable, doing the override in Swift ought to be possible, even if for 
> other reasons it only executed when an instance was created from the Obj-C 
> side.

To be honest, I don’t want it.  I think it would be much better if alloc were 
not exposed to Swift at all.   

However, if it is the case that A) alloc needs to be exposed to support a 
particular functionality, and B) overrides of alloc are not called when 
initializing objects, and therefore don’t really do anything, then C) I would 
want alloc to marked as final so that it’s clear that you can’t really subclass 
it in Swift for any useful purpose.  

So the simple solution is to not expose alloc in Swift.  If alloc must be 
exposed and cannot effectively be overridden, then marking it as final seems 
like a logical thing to do.  

Sincerely,

Michael Patrick Ellard





 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/xcode-users/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to