|
failable initialisers are cool. sort of. i've often lamented the inability of constructors to fail and the factory patterns this creates. that said, it feels like they're there for "the wrong reasons" - interoperability with old two-phase-construction apis.. but hey, if they can be wrapped sufficiently for the static analysis to be reliable, that's fine. presumably this is another nail in the coffin of exceptions on the cocoa platform.
|
# ? Oct 22, 2014 07:15 |
|
|
# ? May 28, 2024 15:41 |
|
rjmccall posted:Yes. Is that not true in Swift? If you've declared it somewhere, and exposed it to ObjC with @objc, that's worth a bug. You know what I just re-tested it and it appears to, but it was not working in my real project. I may have some header madness screwing things up. quote:It's on the bucket list. Er, at least the list of possible values for payload-less enums is. Meaningfully enumerating payloaded enums would probably require static or dynamic metaprogramming; what's your goal? Bridge swift enums to Objective-C so when I create entirely new functionality in Swift (that needs to be consumed by old ObjC classes), I don't have to drop back to ObjC just to define an old-fashioned NS_ENUM. For basic raw enums with no functions that inherit from NSInteger or some other integral type obviously Swift could just emit the appropriate C-style enum even though it doesn't today, but I think it makes more sense to expose them as objects. eg: code:
code:
So that and @protocol circular header references are the two really annoying pain points right now. A class which needs to be included in my bridge header also needs to implement a protocol defined in swift. Oops, no-can-do buster! So I end up with Objective-C files that shadow half my Swift classes just to declare protocols and enumerations. I also ran into this hilariousness: code:
I boiled it down to the simplest case and it appears that calling super.init() instead of super.init(nib,bundle) triggers the failure in initialization. If you call super.init() and don't implement override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) you get a nice crash concerning an unimplemented initializer. OK you say, you're calling the wrong initializer for a view controller... Well smartypants, guess what happens if you inherit from UITableViewController and call super.init(style:UITableViewStyle) like a normal person? It behaves as if you had called super.init(), complete with crashes and missing values.
|
# ? Oct 22, 2014 07:45 |
|
Gul Banana posted:failable initialisers are cool. sort of. i've often lamented the inability of constructors to fail and the factory patterns this creates. Hmm. Initializers serve two sortof different purposes, depending on what they're initializing. The first is what I would call "complete-object initialization". This is when you write Foo(widget: obj) or whatever. To the extent that this is kindof just like a function call that usually returns a new object, it makes sense that it can fail. There's no problem here. The second is what I would call "base-subobject initialization". This is when you're in a subclass's initializer and you write super.init(widget: obj). It's a lot more problematic for this to fail, because it's very intricately tied into the initialization of the object. In a world where initialization sets up useful invariants on objects (most primitively that all fields have been validly initialized, but of course you can have higher-level invariants), but where we also don't want to impose weird restrictions on what methods you can call in initializers (or make such methods behave totally differently at that time, like they do in C++), we have to be really picky about how and when you can fail. And I think that that pickiness reflects a real issue in Objective-C, which is that failing superclass initializers leave the allocated object in a really precarious state that you have to be very careful to program around; e.g. if you want to write a dealloc method on a class with a failable initializer you had better understand what exactly is going to happen when that initializer fails, because you are probably not prepared for it, and your object is not going to be in any kind of consistent state anymore. And even getting that far relies on assumptions about initialization and object invariants that are just deeply problematic. But we're in a difficult position, because there do exist failable designated initializers in Objective-C, and they do pose all these issues, and that makes it really difficult to formalize behavior around them. And the idea of complete-object initialization being able to fail is still really interesting, and it lures people towards these perilous jagged rocks that we don't know how to dissuade them from. So I expect it'll take a lot more iteration, which is terrifying because of how much effort it's taken to even get this far. Object models are hard.
|
# ? Oct 22, 2014 07:51 |
|
Ender.uNF posted:Bridge swift enums to Objective-C so when I create entirely new functionality in Swift (that needs to be consumed by old ObjC classes), I don't have to drop back to ObjC just to define an old-fashioned NS_ENUM. That is a really interesting idea, and I have no idea what to tell you. Metaprogramming, I guess. Ender.uNF posted:That's right, the values set in the initializer are blown away after initialization is done. Guess what happens if someArray is not nillable? Crash! Yeah, so the issue here is that init() is not the designated initializer for UIViewController, and that hasn't been marked in the headers, so we have to be conservative and assume you know what you're doing. Don't super-delegate to a non-designated initializer. Ender.uNF posted:OK you say, you're calling the wrong initializer for a view controller... Well smartypants, guess what happens if you inherit from UITableViewController and call super.init(style:UITableViewStyle) like a normal person? It behaves as if you had called super.init(), complete with crashes and missing values. Ugh. This is so screwed up. The problem is that initWithStyle: does not behave like a designated initializer for UITableViewController, because it doesn't call a designated initializer from its superclass: it calls init, which on UIViewController is a convenience initializer which re-dispatches down to the most-derived class's initWithNibName:bundle:. So, basically, initWithStyle: is not a designated initializer, and when you're super-delegating, you need to be calling the designated initializer, which is initWithNibName:bundle:. I'm sorry this isn't (1) documented and (2) properly annotated in the header.
|
# ? Oct 22, 2014 08:14 |
|
cowtown posted:Am I missing something, or is this just a lexer/parser and nothing else? Hey now they're also kickstarting their own smartphone, it's a lot of work to design a whole phone while maintaining your indie cred.
|
# ? Oct 22, 2014 13:57 |
|
chaosbreather posted:Hey now they're also kickstarting their own smartphone, it's a lot of work to design a whole phone while maintaining your indie cred. Their 'team' appears not to contain any programmers. Or hardware guys. But 3 designers.
|
# ? Oct 22, 2014 19:01 |
|
feedmegin posted:Their 'team' appears not to contain any programmers. Or hardware guys. But 3 designers. This is taking this thread way off topic but these guys are building their own open-source version of Swift, AND a distributed social network, AND their own open-source operating system... quote:With Project Stratosphere, we are building the Indienet. But now they're also hardware manufacturers AND mobile application developers?
|
# ? Oct 22, 2014 19:57 |
|
So I'm serializing some JSON into a dictionary. It seems like the ordering is not being completely honored and I just can't guess why. My inputs to the REST API look like "11776,11880,13220". Sending a request to the endpoint in my browser gets me a dictionary with the keys written in this order. Enumerating the keys in the JSON dictionary that comes back from NSJSONSerialization gets me these values: "11776,13220,11880" Is it normal to see this behavior? Is there any reason it happens to be in this order as opposed to any other?
|
# ? Oct 22, 2014 23:39 |
|
Dictionaries are inherently unordered, if you need values in a specific order you have to use an array.
|
# ? Oct 22, 2014 23:44 |
|
Yeah, just strange that it's in a consistent but wrong order. I'm mostly irritated with the guys designing the API as there isn't much reason for it to be a dictionary as opposed to an array.
|
# ? Oct 22, 2014 23:57 |
|
I'm not sure what exactly determines the order that you get entries back when enumerating a Swift or NSDictionary, but it doesn't surprise me too much that it appears to be consistent under the same circumstances. You just can't rely on it always being that way. If you don't have control over the format you get the data in, you'll have to process the values into an array and sort it yourself.
|
# ? Oct 23, 2014 00:03 |
|
Building a hash table is a deterministic process unless your hash function uses raw pointer values or something. (And even that is only non-deterministic if something about your system makes it so e.g. if the dynamic linker uses ASLR, or if malloc starts at a different base address in every process, or something else along those lines.) And iterating it will typically just visit buckets in order, so iterating it multiple times will result in the same sequence unless you change the structure of the table in between, e.g. by adding enough entries to force the table to grow. Of course, none of that is guaranteed, but that's why it happens to work out that way. ETA: Mmm, I just remembered that there are hashtable implementations that do incorporate a random, table-specific value whenever creating a new hashtable. That serves several purposes: one, like ASLR, it makes the hashtable harder to exploit; two, it makes the instability of iteration much more obvious, reducing the odds that somebody accidentally relies on it; and three, it can make help protect against weak hash functions, depending on how you incorporate the seed. But I don't think NSDictionary or Swift.Dictionary do this. rjmccall fucked around with this message at 00:16 on Oct 23, 2014 |
# ? Oct 23, 2014 00:09 |
|
rjmccall posted:That is a really interesting idea, and I have no idea what to tell you. Metaprogramming, I guess. You can't directly set the style so there is no possibility of calling some other initializer. That makes it impossible to have a UITableViewContoller-derived subclass in swift with an initializer... unless you're banning grouped table views rdar://18747436 Simulated fucked around with this message at 08:28 on Oct 23, 2014 |
# ? Oct 23, 2014 08:13 |
|
Ender.uNF posted:You can't directly set the style so there is no possibility of calling some other initializer. That makes it impossible to have a UITableViewContoller-derived subclass in swift with an initializer... unless you're banning grouped table views Wow, that is really terrible. Trying to escalate.
|
# ? Oct 23, 2014 19:43 |
|
"All stored properties of a class instance must be initialized before returning nil from an initializer." What is the point of this? Why can't I return nil at ANY point during initialization?
|
# ? Oct 24, 2014 00:30 |
|
fleshweasel posted:"All stored properties of a class instance must be initialized before returning nil from an initializer." My guess is so that the deinitializer can be called cleanly.
|
# ? Oct 24, 2014 00:36 |
|
pokeyman posted:My guess is so that the deinitializer can be called cleanly. Yep. I think we'd like to loosen this restriction over time, but we'd need to figure out the exact interplay with subclass initializers. This is complicated enough in a pure-Swift world, but the requirement for ObjC interop makes it really difficult. So here's the problem. A complete object is a collection of base-class subobjects, and it's fully constructed if all of the properties in all of those subobjects have been assigned. ObjC subobjects are fully constructed during allocation, not initialization; this works because we assume that zero-initialization is good enough for C/ObjC types, and C++ class types are required to provide a default constructor. That doesn't work in Swift, mostly because we have types that we aren't willing to give reasonable default states to; non-optional class references are the most obvious example. From a single Swift class's perspective, it's fully constructed after the super.init call returns successfully or (if in a root class) after you've assigned all the properties; this works because Swift initializes properties "on the way down". You can't safely destroy an object until it's been fully constructed, which is why Swift prevents arbitrary uses of self until that point. Once an object is fully constructed, you have to assume that there might be arbitrary references to it (set up, for example, by the superclass's initializer), so the only reasonable thing that we can do if an initializer fails at this point is release self and return. But if you want to fail before the object is fully constructed, that doesn't work; you definitely can't call deinit(), which is allowed to use "self" in unrestricted ways, but even "primitive" deinitialization may try to destroy properties which are still uninitialized. So you have to be able to unwind initialization, including up through subclasses, and delay deallocation until you've unwound all the way up. And I think it's possible to make that interact sensibly with the ObjC initialization protocol, including both ObjC superclasses and ObjC subclasses, but it's definitely tricky.
|
# ? Oct 24, 2014 01:37 |
|
This was in my dream last night
|
# ? Oct 27, 2014 01:35 |
|
My waking nightmare.
|
# ? Oct 27, 2014 02:12 |
|
code:
Oh wait, in a tuple? gently caress right off. rdar://18792507 Also confirmed rdar://18747436 is still alive and well in 6.1.
|
# ? Oct 28, 2014 06:33 |
|
Today's random bug rdar://18807413 AKA "7 is a magic number":code:
Trying to do serialization/deserialization has me very nearly tossing this Swift code out and doing it in Objective-C. There's probably a better way that I just can't see right now, but so far its just a lot of manual ["key" : self.key] crap everywhere, and the inverse on the other side. I was trying to coalesce all the json-swift JSValue.errors to see if any errors are present. It was working great up until I hit a larger class. The funny part is in C# I would just use the JSON serializer and literally be done in five minutes; it would automatically map read/write properties bidirectionally, handle arrays/dictionaries, nested values, etc.
|
# ? Oct 29, 2014 07:15 |
|
I posted this earlier in the thread, but I wrote a little JSON handler that might be helpful for you: https://gist.github.com/dizzywhip/046691faa20ef5a1b0db It's still a little more cumbersome than using JSON in Objective-C or C# when you're reading data due to the type safety, but I actually like it a lot because it kind of forces you to properly handle unexpected data.
|
# ? Oct 29, 2014 07:48 |
|
I'm having trouble implementing the MKMapViewDelegate viewForAnnotation method. Conventional wisdom seems to suggest that the body of this method needs to return a nil for the user location annotation to get the proper appearance for it, like so: let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("MKAnnotationView") ?? MKAnnotationView() if annotationView is MKUserLocation { return nil } This fails to compile with the error "MKUserLocation is not a subtype of MKAnnotationView." The legacy way of doing it with Swift syntax appears to be: annotationView.isKindOfClass(MKUserLocation). That compiles, but doesn't give the default appearance for the location dot. Am I screwed on writing this in Swift? Is it time to bust out the Objective-C for my map view delegate? edit: annotationView.annotation.title == "Current Location" works, but it smells. edit again: Finally realized that MKUserLocation is an MKAnnotation, not an MKAnnotationView. brap fucked around with this message at 18:04 on Nov 1, 2014 |
# ? Nov 1, 2014 02:30 |
|
Can I just say that this language is making me more excited about programming that I've been for years. I work in an embedded world, where everything is C, because of ~speed!~ and ~embedded!~, but for fucks sake, 80% of what we do is managing a dozen state machines, sending messages and events around, and receiving button presses and making LEDs blink in one of two colors. I'd love for all this to be written in a safe, practical, concise language.
|
# ? Nov 3, 2014 07:59 |
|
Not sure if this is a style question or not. Is there any functional difference between referring to properties with self.property vs. just property? I use the former because I think it clarifies that it's a class property and not just a local variable, but I'm wondering if others are doing the same.
|
# ? Nov 3, 2014 16:02 |
|
I've been favoring not using self unless for whatever reason it's required. Which right now is closures, or cases where a variable shadows something in a different scope. Hope to hear some others respond. Edit: I feel like no best practices are developing because no one wants to be wrong when language changes break previous assumptions. Kallikrates fucked around with this message at 16:25 on Nov 3, 2014 |
# ? Nov 3, 2014 16:07 |
|
lord funk posted:Not sure if this is a style question or not. Is there any functional difference between referring to properties with self.property vs. just property? I use the former because I think it clarifies that it's a class property and not just a local variable, but I'm wondering if others are doing the same.
|
# ? Nov 3, 2014 16:38 |
|
lord funk posted:Not sure if this is a style question or not. Is there any functional difference between referring to properties with self.property vs. just property? I use the former because I think it clarifies that it's a class property and not just a local variable, but I'm wondering if others are doing the same. It is a style question, and I don't think you meant "class properties". Anyway I do what I do for ivars in Objective-C: skip the self unless it's needed because of shadowing. I feel like I have even more of a leg to stand on for this in Swift, what with all the type inferencing. Though if you put an underscore in your ivar names that works well as a sigil. In conclusion, Libya is a land of contrast.
|
# ? Nov 3, 2014 19:40 |
|
I'm somewhat embarassed to admit it, but I never quite got a good handle on using the Interface Builder -- the old Objective C tutorial book I had wanted to do things the hard by hard-coding everything by setting CGRects and all, but I couldn't get very far with it and the result of that meant I just only ended up with a rather nebulous idea of how View Controllers and everything even worked. I need to pick up making GUIs in iOS pretty quickly now, but the majority of the tutorials I find are still Objective C oriented. Is the Interface Builder for Swift any different?
|
# ? Nov 3, 2014 22:51 |
|
Interface Builder is not particularly related to Objective-C or Swift except that you can create outlets to UI elements defined in IB or target actions in your view controller.
|
# ? Nov 3, 2014 23:06 |
|
Morroque posted:I'm somewhat embarassed to admit it, but I never quite got a good handle on using the Interface Builder -- the old Objective C tutorial book I had wanted to do things the hard by hard-coding everything by setting CGRects and all, but I couldn't get very far with it and the result of that meant I just only ended up with a rather nebulous idea of how View Controllers and everything even worked. Nah it's pretty much identical. Instead of IBAction you use @IBAction. Little stuff like that.
|
# ? Nov 4, 2014 02:54 |
|
How do I write an extension method that is nil-safe (i.e. can be invoked on an optional)?
|
# ? Nov 6, 2014 21:13 |
|
fleshweasel posted:How do I write an extension method that is nil-safe (i.e. can be invoked on an optional)? If you mean that you specifically want to extend SomeType?, the answer is that you would write extension SomeType? but don't bother, that's not supported (yet). Otherwise, you can make it a global function. I'm skeptical that making a "nil-safe" method in that sense is actually a good idea, though.
|
# ? Nov 9, 2014 11:06 |
|
rjmccall posted:If you mean that you specifically want to extend SomeType?, the answer is that you would write extension SomeType? but don't bother, that's not supported (yet). Otherwise, you can make it a global function. I've written something like code:
Objective-C code:
|
# ? Nov 9, 2014 12:37 |
|
The reason is simply that it allows for chaining and reduction of nil checks.code:
code:
|
# ? Nov 9, 2014 20:23 |
|
fleshweasel posted:The reason is simply that it allows for chaining and reduction of nil checks. Not that I disagree - I too have run into situations where extending SomeType? would be useful - but you can already chain optional method invocations that way.
|
# ? Nov 10, 2014 18:58 |
|
I'm finding myself wanting to use tuples as multi-part dictionary keys from time to time because of how easy they are to construct syntactically (imagine a table mapping something like (KeyboardAppearance, ControlState) to UIColors). I hate the extra effort of defining a full struct for this *and* the hash/equality methods. Would it be possible for the language to make a tuple type conform to Hashable/Equatable if all of the types of their elements conform to Hashable/Equatable? Flobbster fucked around with this message at 16:05 on Nov 11, 2014 |
# ? Nov 11, 2014 16:01 |
|
It's a future direction that we want to pursue when, y'know, we have a more stable base for the existing language. It's easy to do if we want to hardcode tuples and Hashable/Equatable; it requires a lot more infrastructure to make a general feature, mostly because tuples are variadically generic.
|
# ? Nov 11, 2014 19:17 |
|
I'm always happy to wait for a well-designed general feature than a specific hack I'm really looking forward to what Swift brings to the table w.r.t. generics overall. From what I've already seen in the standard library and what you've talked about wanting to do, I'm hoping that we're going to start getting a lot closer to the power of C++ templates than a lot of other modern languages since then (at least as close as you can get without doing the same substitution-only approach used there). On that note, I was recently trying to write a generic matrix ADT that would have a fixed size at initialization time, but when I tried to fill the array using the (count:repeatedValue:) initializer, I hit a stumbling block: code:
|
# ? Nov 12, 2014 02:59 |
|
|
# ? May 28, 2024 15:41 |
|
Flobbster posted:I'm always happy to wait for a well-designed general feature than a specific hack I'm really looking forward to what Swift brings to the table w.r.t. generics overall. From what I've already seen in the standard library and what you've talked about wanting to do, I'm hoping that we're going to start getting a lot closer to the power of C++ templates than a lot of other modern languages since then (at least as close as you can get without doing the same substitution-only approach used there). This is equivalent to the "new" constraint in C# and I second the motion. Also big news: very shortly we will be shipping our first Swift code. Other than a few pain points the overall experience makes writing Objective-C seem like COBOL already.
|
# ? Nov 12, 2014 06:40 |