Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Doh004
Apr 22, 2007

Mmmmm Donuts...
I don't see iOS 7 simulators in Xcode 7 Beta 5 to download. Will they be downloadable in the near future so we can still test for iOS 7?

Meat Street posted:

That's one way, or you can make the methods you want to test (and the classes they're declared in) public. Either way the issue you're running into is that your classes aren't exposed outside the app module, so your test target can't see them.

Sorry I forgot to respond to this. My classes are public; however, when trying to load the storyboard, it assumes it's in the UnitTest module.

Doh004 fucked around with this message at 14:58 on Aug 11, 2015

Adbot
ADBOT LOVES YOU

lord funk
Feb 16, 2004

Is there something other than using po in the debugger that I should be aware of? po is constantly finding new ways to not show me anything at all, even as the local variable list shows me the objects I want to inspect.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer
It may not solve your exact issue, but everyone in the world should be using chisel:

https://github.com/facebook/chisel

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

ultramiraculous posted:

It may not solve your exact issue, but everyone in the world should be using chisel:

https://github.com/facebook/chisel

For bmessage alone, if nothing else.

Ari's obj.io post about Chisel is also a great introduction to using lldb well: http://www.objc.io/issues/19-debugging/lldb-debugging/

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

lord funk posted:

Is there something other than using po in the debugger that I should be aware of? po is constantly finding new ways to not show me anything at all, even as the local variable list shows me the objects I want to inspect.

LLDB gets very confused with certain Swift constructs. I haven't been able to find a pattern yet. Seemingly simple classes will cause the debugger to say it can't po self or some local variable. Closures seem to make it worse. In every case the variables pane shows everything just fine.

Like the random nonsense errors you get when the contents of a closure are invalid you just work around it.

Doh004
Apr 22, 2007

Mmmmm Donuts...

Ender.uNF posted:

LLDB gets very confused with certain Swift constructs. I haven't been able to find a pattern yet. Seemingly simple classes will cause the debugger to say it can't po self or some local variable. Closures seem to make it worse. In every case the variables pane shows everything just fine.

Like the random nonsense errors you get when the contents of a closure are invalid you just work around it.

I've given up trying to make sense of it. If I really need to debug something really badly, a quick clean, clean build folders and wiping out derived data fixes my problems (sometimes). If that doesn't work, well I just give up for the day and go home.

lord funk
Feb 16, 2004

Syntax head scratcher:

In Darwin >> C >> Math:

code:
public func __sincospif(__x: Float, _ __sinp: UnsafeMutablePointer<Float>, _ __cosp: UnsafeMutablePointer<Float>)
My call:

code:
    var a = angle
    var c: Float = 0.0
    var s: Float = 0.0
    
    __sincospif(a, UnsafeMutablePointer<Float>(s), UnsafeMutablePointer<Float>(c))
Error:
code:
Cannot invoke '__sincospif' with an argument list of type '(Float, UnsafeMutablePointer<Float>, UnsafeMutablePointer<Float>)'

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Sorry. Crappy error message and some poorly-documented language features.

For the convenience of using C APIs like this, you can construct an argument of type UnsafeMutablePointer<T> by passing a local variable inout, i.e. by passing &T. As always with inout, this forms an association between the argument and the source l-value that's only guaranteed to persist for the duration of the call.

So what you want is just __sincospif(a, &s, &c).

Obviously, if this is an API you use frequently, you should probably wrap it in a function returning a tuple.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Starting to really feel the pain of Xcode 7 forcing a Swift 2 upgrade. It makes maintaining branches difficult.

I totally understand wanting to push the language forward and I agree with it, but perhaps the compiler & standard library could support the old stuff (but deprecated) for a single release. If we could just get away with both for six months it would be relatively painless.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Yeah, I have different projects that use different Swift versions and I'm afraid I'm going to need a VM to run a different Xcode in.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Installing Xcode 6 and 7 side-by-side works fine. I've been switching between them many times per day ever since the first beta came out, and literally the only problem I've encountered is that you have to explicitly exit the simulator when switching or dumb things happen.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

Plorkyeran posted:

Installing Xcode 6 and 7 side-by-side works fine. I've been switching between them many times per day ever since the first beta came out, and literally the only problem I've encountered is that you have to explicitly exit the simulator when switching or dumb things happen.

That stops being so much fun when you have to keep an iOS 9 branch going while working on other feature branches. You basically can't interact with the iOS 9 branch.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Hmm, I was having problems with xctool, but I'll try again.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
xctool links against private Xcode frameworks, so I believe you'll want to rebuild/reinstall it whenever you xcode-select to some other version (and whenever you update Xcode). Maybe you can build separate copies as xctool6 and xctool7?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Ender.uNF posted:

That stops being so much fun when you have to keep an iOS 9 branch going while working on other feature branches. You basically can't interact with the iOS 9 branch.

Maintaining Swift 1.2 and Swift 2.0 versions of code has certainly been an utter nightmare, but having to keep track of which copy of Xcode I'm looking at is one of the smallest of the annoyances. I guess not being able to use the iOS 9 SDK with Swift 1.2 is an unnecessary headache.

Dirk Pitt
Sep 14, 2007

haha yes, this feels good

Toilet Rascal
Has anyone gotten swift frameworks to build with a build configuration other than Default or Release? We have two "Release" Configurations, one for hockey app and one for the app store and I duplicated the release build configuration for the product, and I get an annoying error saying "no such module" whenever I try to build for AppStore configuration.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

Plorkyeran posted:

Maintaining Swift 1.2 and Swift 2.0 versions of code has certainly been an utter nightmare, but having to keep track of which copy of Xcode I'm looking at is one of the smallest of the annoyances. I guess not being able to use the iOS 9 SDK with Swift 1.2 is an unnecessary headache.

I don't think we are talking about the same things.

Xcode 7 is the only version that can use the iOS 9 SDK.
Xcode 7 will only build Swift code that uses Swift 2 syntax.
The changes make it extremely difficult to merge changes from other branches into our iOS 9 branch or vice-versa.
This directly leads to either making iOS 9 changes blind, fighting merge hell, or constantly re-running the conversion.


Separate question: can anyone make the case for not having an optional assignment operator?
code:
infix operator ?= { associativity right precedence 90 }
func ?= <T>(inout lhs: T, rhs: T?) {
    if let rhs = rhs {
        lhs = rhs
    }
}

Kallikrates
Jul 7, 2002
Pro Lurker
We thought about adding it, wanted to minimize new operators at the time. The more I use ?? the more it makes sense though. It will burn people that abuse didSet {} etc for side -effects. (a good thing?)

Doh004
Apr 22, 2007

Mmmmm Donuts...
Anyone have any tips on how to cut down on compilation times? Or rather, how to find out why some files take forever to compile? I ran my build in XCTool and almost every one of our swift files take > 1000ms to compile, with the worst one coming in at > 6000ms.

Google has suggested a tool to merge all swift code into one big file (because multiple files decreases compilation time), cutting down on nested type inference and last but not least: writing code in Objective-C.

Kallikrates
Jul 7, 2002
Pro Lurker
Xcode7 seems to have improved it quite a bit.

Outside of that I noticed that putting logic in extensions that are then referenced in multiple places can have a really bad effect. For example a method in an extension on UIViewController. I don't have measurements but whenever I need to make a change in one of these files, the resulting build time is significantly degraded. So I have been using less extension and more combining related classes in files.

Unlike Obj-c where even very small classes would have their own file I don't do that for Swift. Small classes live along side the viewcontroller that uses them for example.

Doh004
Apr 22, 2007

Mmmmm Donuts...

Kallikrates posted:

Xcode7 seems to have improved it quite a bit.

Outside of that I noticed that putting logic in extensions that are then referenced in multiple places can have a really bad effect. For example a method in an extension on UIViewController. I don't have measurements but whenever I need to make a change in one of these files, the resulting build time is significantly degraded. So I have been using less extension and more combining related classes in files.

Unlike Obj-c where even very small classes would have their own file I don't do that for Swift. Small classes live along side the viewcontroller that uses them for example.

Interesting about the extensions, that kinda sucks. But yeah, good call on Xcode 7. Good to hear 7 is already doing better.

brap
Aug 23, 2004

Grimey Drawer
What's the current way to write a function which consumes any sequence type that can be iterated? I pretty much just want the equivalent to IEnumerable<T> but it looks like we still have

myFunc<S : SequenceType where Sequence.Generator.Element == someType>(seq: S) { ... }

This is way too clunky.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Yeah, it sucks. I don't think there's an alternative yet, though.

lord funk
Feb 16, 2004

Is it possible to share a struct type between a Metal shader file (C++) and the rest of my Swift code that uses SIMD vector types? Swift 2 supports SIMD, and you can import it into the shader file, but I can't seem to bridge the two so I can just create one struct that they both see.

lord funk
Feb 16, 2004

Please school me on retain / release in array iterations.

Here is a test app with a big array that I iterate through each frame:

code:
class TestClass {
    var value: Double = 0.0
    func calculate() {
        value = Double(random())
    }
}

class ViewController: UIViewController {
    
    let testArray: [TestClass] = {
        var build: [TestClass] = []
        for _ in 0..<100000 {
            let t = TestClass()
            build.append(t)
        }
        return build
    }()

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        let displayLink = CADisplayLink(target: self, selector: "displayLinkTicked")
        displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
    }

    func displayLinkTicked() {
        for testClass in testArray {
            testClass.calculate()
        }
    }
}
I was surprised to see that the majority of the work done in the loop is retain / release calls (93%):



My assumption is that this is ARC doing its thing. If this were Objective-C, I'd disable ARC for the file to avoid this. What are my options in Swift? It seems really wasteful to retain / release each object when I know they aren't going anywhere.

brap
Aug 23, 2004

Grimey Drawer
Try using an array of structs if you can get away with it.

lord funk
Feb 16, 2004

fleshweasel posted:

Try using an array of structs if you can get away with it.

Seems like 6 of one 1/2 dozen of the other. Now it's mainly swift_unpin and swift_tryPin.

(with struct instead of class):

its HIM
Oct 22, 2013
Swift's eagerness to retain was identified pretty early on; I'd think they'd have fixed it by now if it were fixable. Does changing the optimization level have an effect?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

lord funk posted:

Seems like 6 of one 1/2 dozen of the other. Now it's mainly swift_unpin and swift_tryPin.

(with struct instead of class):


Those are from accesses to the array itself and should be present regardless. If they're now dominating, it should mean you dropped down a level of overhead.

If that's not good enough for your performance needs, you should be able to use unsafe buffers and/or unowned(unsafe) variables until your problem goes away. But, also, please file a radar showing the problem you're having.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

its HIM posted:

Swift's eagerness to retain was identified pretty early on; I'd think they'd have fixed it by now if it were fixable.

That's not really the nature of the optimization problem.

its HIM
Oct 22, 2013

rjmccall posted:

That's not really the nature of the optimization problem.

I don't know what you're trying to tell me, but I'm just remembering way back when tons of extraneous retain/release calls were a common performance complaint (esp. versus identical code in Obj-C) and you devs on the dev forums were suggesting that the optimizer would improve over time (and/or you guys might "re-evaluate in future releases"). I'd assume at this point that stuff is as efficient as it can be. Which seems to be what you're saying.

toiletbrush
May 17, 2010
I came across a surprising compiler confuser just now...
code:
let x = (0..<10).filter { $0 % 3 == 0 }
...compiles, but this doesn't...

code:
let x = (0..<10).filter { $0 % 3 == 0 || $0 % 5 == 0 }
...even if you give 'x' an explicit type.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
I'm trying to write a wrapper around pthreads (I'm doing something sooper sekrit and I want to be ready for Swift to go open source and run on other platforms and not tie myself to Foundation or GCD :v: ), but I'm hitting a super confusing retain issue:

code:
class PeeThread {
  private var thread = pthread_t()
  private var function: () -> ()

  init(function: () -> ()) {
    self.function = function
  }

  deinit {
    print("thread deallocated")
  }

  func start() {
    // Explicit retain to ensure self doesn't go away before the thread proc starts
    var retainedSelf = Unmanaged.passRetained(self)

    // arg in this closure is an UnsafeMutablePointer<Void>
    pthread_create(&thread, nil, { arg in
      sleep(1)
      let selfPtr = UnsafeMutablePointer<Unmanaged<PeeThread>>(arg)
      let self_ = selfPtr.memory.takeRetainedValue()
      self_.function() // CRASH: self_ why are you nil here??
      return nil
    }, &retainedSelf)
  }
}

// Do this stuff in a function and don't return the thread so it get released when
// it goes out of scope
func doThreadThings() {
  let thread = PeeThread() {
    print ("foo bar")
  }
  print("starting thread")
  thread.start()
}
doThreadThings()

sleep(4) // Keep the process alive a bit
I'm using Unmanaged to explicitly retain my PeeThread object so I can make sure it stays alive until I get into the thread function, but for some reason .takeRetainedValue() is returning a nil reference (self_ is 0x0000000000000000 in the debugger). The object isn't being deallocated because the print statement in deinit is never being executed, like I would expect.

This seems like it should be pretty cut and dry manual memory management—what's going on here?

I'm also running into a compiler crash when I try to make that class generic (to have a return value from the thread closure); I filed rdar://22592331.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

its HIM posted:

I don't know what you're trying to tell me, but I'm just remembering way back when tons of extraneous retain/release calls were a common performance complaint (esp. versus identical code in Obj-C) and you devs on the dev forums were suggesting that the optimizer would improve over time (and/or you guys might "re-evaluate in future releases"). I'd assume at this point that stuff is as efficient as it can be. Which seems to be what you're saying.

Nah, what I mean is actually the reverse: there's literally always room for further optimization. There's definitely a lot more we can do to remove retains and releases.

One of the challenges with Swift is that we try very hard to be fully safe in ways that ObjC ARC doesn't. For example, in ObjC, we don't retain just because you loaded from a variable, which means your program could crash if you assign to that variable during the current operation. Swift has a stricter safety mandate, and so we do retain there, hoping to eliminate it later. That means that there are a lot of paranoid retains and releases in Swift, and so the ARC optimizer has a much bigger job.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Flobbster posted:

I'm using Unmanaged to explicitly retain my PeeThread object so I can make sure it stays alive until I get into the thread function, but for some reason .takeRetainedValue() is returning a nil reference (self_ is 0x0000000000000000 in the debugger). The object isn't being deallocated because the print statement in deinit is never being executed, like I would expect.

This seems like it should be pretty cut and dry manual memory management—what's going on here?

I'm also running into a compiler crash when I try to make that class generic (to have a return value from the thread closure); I filed rdar://22592331.

What you're doing with unsafe pointers isn't safe; you're taking the address of a local variable and passing it to pthread_create. In theory this is a form of capture, but since this is C interop, there's no way for us to kept the local variable alive for the correct duration to make that work; instead, you just end up creating a dangling pointer to a variable in a dead stack frame. Formally, we say that the link between the pointer and the variable lasts only as long as the call.

Basically, I'm saying that when working with pointers and C APIs, you generally still need to be reasoning about where those pointers point.

You can turn your Unmanaged directly into an unsafe pointer to use as your pthread context, then cast it back in the invocation function.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
:doh:

Duh, thanks. I even thought about this when I was passing "var self_ = self; ... &self_" into the function originally, but then I was like "that won't retain it, and the variable is local." Somehow when I started using Unmanaged to solve the first problem, I just lost track of the other part.

lord funk
Feb 16, 2004

rjmccall posted:

If that's not good enough for your performance needs, you should be able to use unsafe buffers and/or unowned(unsafe) variables until your problem goes away.

Could I get some help on this? I've tried unsafe buffers and they still retain / release within the loop. I've tried using Unmanaged; same thing. And using unowned seems to actually add weak_retain and weak_release in addition to the original retain / release.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
unowned(unsafe) is its own thing, akin to __unsafe_unretained.

If you're seeing retains and releases within a loop with unsafe buffers, you're either using them wrong (e.g. not constructing the unsafe buffer outside of the loop) or your retains aren't related to your array buffer. Maybe they're related to your array elements?

lord funk
Feb 16, 2004

Okay so I switched to using UnsafeMutablePointer<MyClass>, and iterating over it instead of Array does get rid of the retain calls. However...

rjmccall posted:

Maybe they're related to your array elements?

It seems like the function the class performs makes a difference. When I iterate over 100000 instances of TestClass and call calculate():

code:
class TestClass {
    var value = 1.0
    
    func calculate() {
        value = value * 1.00001
    }
}
There are no retain calls. But this:

code:
class TestClass {
    var value = 1
    
    func calculate() {
        value = random()
    }
}
All of the retain calls come back. I'm not sure what's being retained; is it the class? the value var?

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Yes, the operation you do on the array element affects whether the compiler has to retain it for safety. In this case, calling a method on a class instance forces the caller to guarantee that the instance stick around. That can be elided if the method call can be devirtualized and inlined.

If you're actually concerned with performance on the level of retains and releases, try to avoid classes and dynamic dispatch.

  • Locked thread