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.
 
  • Post
  • Reply
Froist
Jun 6, 2004

Not really sure whether this or the GameDev thread is the best place to post this, but I'll try my luck here first.

Does anyone have experience with Game Center? This is more of a logical problem than technical, but the documentation (GameKit Guide) doesn't make a great deal of sense to me. First it states:

GameKit Guide posted:

In addition to using player identifiers in your interactions with Game Center, your application should also use player identifiers whenever you need to associate information with a specific player. For example, if your game stores data on a player’s device to track the player’s progress in your game, you should use player identifiers to distinguish between multiple players playing on the same device.
.. And later, referring to multitasking:

GameKit Guide posted:

As soon as your game moves to the background, the value of the local player object’s isAuthenticated property becomes invalid and remains invalid until your game moves back to the foreground, Game Kit authenticates the player, and your authentication handler is called. Your game must act as though there is not an authenticated player until your completion handler is called. Once your handler is called, the isAuthenticated property is valid again, and holds the whether a player is authenticated on the device.

The first part implies that all my save data must be stored separately per-player. That's fine - at the moment my data is just in a dictionary so I can add a nested dictionary at the top level keyed by the player ID.

The second part is the problem; to me this implies that if a player is in the middle of a game, sends the app to the background, then returns and completes a game before the completion handler is called (eg slow network), that progress should be saved under the 'unauthenticated' user rather than their own. From the player's view who was signed in for the start of the game, never explicitly signed out, and will be auto-signed in again seconds later this seems quite illogical. To me it makes more sense to save this progress as an unauthenticated user if I DO receive a callback to the completion handler saying the user isn't authenticated (or it's a different user), but otherwise to treat it as if the last-known player is still logged in.

I guess the other way to read it is that "act as though there is not an authenticated player" is actually just referring to Game Center rather than being tied to the first quote, and means "don't make any Game Center calls until the completion handler is called", but again it feels wrong not to submit a high score that they may set in this brief window. Maybe they should be buffered up until the handler's called?

Following on from hedgecore's question, being that this is my first app near to completion, is this the kind of thing that Apple would pull you up for in a review?

Adbot
ADBOT LOVES YOU

Doc Block
Apr 15, 2003
Fun Shoe
With regards to releasing your app, like pokeyman said, delete your DerivedData folder and rebuild from scratch before you submit your app.

Put
code:
alias fuxcode='rm -rf ~/Library/Developer/Xcode/DerivedData'
at the end of ~/.profile

Then close Xcode, open Terminal.app, and do
code:
fuxcode
Then open Xcode back up, rebuild your app, and submit it.

Test on as many different devices as you can. Know someone with an iPhone 3GS or original iPad? See if they'll be a tester for you. Ditto for any kids you know with an iPod Touch. A lot of iOS developers recommend TestFlight, which supposedly makes having beta testers easier (I haven't used it).

I've been pretty lucky so far, and Apple hasn't rejected my apps or any of the updates I've submitted, but here's some tips I've heard from others:

- Like others in this thread have said, set your release date well into the future, and set your app to be released on that date instead of as soon as it's approved. This will give you an exact date you can tell reviewers and such, and by setting it a good ways into the future you can still have time to resolve any issues without blowing your announced release date. AFAIK you can always move up the release date once Apple has approved the app.

- Some have suggested that Thursday is the best day to have your app release on if you want it to be successful. I don't know if this is pure superstition or if there ever was a reason, but I've heard it from a few people.

- Don't mention Android, or any other non-Apple platforms your app/game is available on.

- They really mean it when they say don't use private APIs.

- Some people have been lucky and had apps approved after just a few days. Others have had their apps sit in the "Waiting for Review" queue for weeks. For most people it seems to be 5-10 days. And yes, Apple reviewers work on the weekends and late at night. (I've had updates approved on Saturdays and after 9PM Pacific time).

Doc Block fucked around with this message at 23:26 on Sep 3, 2012

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Froist posted:

I guess the other way to read it is that "act as though there is not an authenticated player" is actually just referring to Game Center rather than being tied to the first quote, and means "don't make any Game Center calls until the completion handler is called", but again it feels wrong not to submit a high score that they may set in this brief window. Maybe they should be buffered up until the handler's called?

Haven't spent five minutes with GameKit but this reading is how I understand it. Don't send poo poo up to Game Center until it's authenticated, and by the way it reauthenticates when entering the foreground.

I'm quite certain they aren't recommending that you lose data (e.g. a high score).

Buffering until Game Center authentication also makes sense if they're temporarily playing offline, so you'd probably want to do this anyway.

zergstain
Dec 15, 2005

Why might all bindings involving a certain key path suddenly stop working? I got a breakpoint set at the property, and every time it's hit, the property isn't nil, yet the stuff I have bound to it thinks it is.

Edit: Turns out the null key was higher up in the path. It seems to be when I set the value via direct assignment, observers aren't notified of the change. Is using "[self setFoo:bar]" rather than "foo = bar" the general best practice?

zergstain fucked around with this message at 04:26 on Sep 4, 2012

hedgecore
May 2, 2004

pokeyman posted:

The big one I guess is thoroughly test it from a completely clean build (i.e. delete DerivedData) on a device other than the one you mostly use for debugging. You don't want to get caught with e.g. an old nib hanging around on your development device that'll crash a release version.

Oh, and set the release date to a few months from now so you control when it gets released after successful review.

And good luck!


Doc Block posted:

With regards to releasing your app, like pokeyman said, delete your DerivedData folder and rebuild from scratch before you submit your app.

Thank you both for your tips! I already clear that folder out regularly, but it's a good reminder for me to do so before my final build. The future release date is a great idea as I do want to control it (but also want to make sure I'm approved).

I've been using TestFlight and have heard nothing but success from iPhone 4/4S and iPod touch users. Gotta round out a few more things before I can try and sell 1.0, but I'm excited.

tarepanda
Mar 26, 2011

Living the Dream

tarepanda posted:

What's up with AVCaptureSession blocking audio playback? Was that ever fixed?

I've tried with AudioServicesPlaySystemSound and AVAudioPlayer, no sounds at all...

Got it. Add the AudioToolbox framework and:

code:
        #import <AudioToolbox/AudioToolbox.h>

        SystemSoundID soundID;
        NSURL *soundFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource: @"mysound" ofType:@"wav"]];
        AudioServicesCreateSystemSoundID((__bridge_retained CFURLRef) soundFile, &soundID);
        AudioServicesPlaySystemSound(soundID);
Aaaand it works. Go figure.

Froist
Jun 6, 2004

pokeyman posted:

Buffering until Game Center authentication also makes sense if they're temporarily playing offline, so you'd probably want to do this anyway.

See, this is kind of the issue, the documentation doesn't seem to have been updated since iOS 4. In iOS 5 they can be playing offline but you will still get a callback to your completion handler if there's enough cached info in Game Center to work out who they are. Similarly you can register high scores and even view cached leaderboard data when offline just by making the regular calls, they'll be automatically stored up and uploaded once the user's online (the documentation doesn't mention this at all, I found it out from watching one of the WWDC videos). So the only problem case is the small window between "application resume" and "completion handler called".

In general what you're saying makes sense and fits with what I was thinking though, so I'll go with that.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



zergstain posted:

Why might all bindings involving a certain key path suddenly stop working? I got a breakpoint set at the property, and every time it's hit, the property isn't nil, yet the stuff I have bound to it thinks it is.

Edit: Turns out the null key was higher up in the path. It seems to be when I set the value via direct assignment, observers aren't notified of the change. Is using "[self setFoo:bar]" rather than "foo = bar" the general best practice?

Yes. Using either of the following ensures that notifications are posted. Also of course any additional logic you may have put in your setters/getters.

Objective-C code:
self.foo = bar;
//or (they're functionally equivalent)
[self setFoor:bar];
Using foo = bar will change an ivar (or even some local variable shadowing it) directly, no notifications.

Presumably you have @synthesize foo = foo; with an ivar called foo? You should avoid doing that (having the property and the ivar have identical names), it only creates confusion. In newer versions of XCode you can skip @synthesize altogether and it will synthesize to _foo.

You almost always want the notifications to fire. I generally only use direct access _foo = foo; in init methods before I return self.

tarepanda
Mar 26, 2011

Living the Dream
Speaking of notifications, how exactly do they work? Could I make it so that every time I change a UIImage, an associated label's text also changes?

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



tarepanda posted:

Speaking of notifications, how exactly do they work? Could I make it so that every time I change a UIImage, an associated label's text also changes?

Yeah, there are many ways to do this. Personally, I would probably have the controller expose two properties/IBOutlets: the image, and its label. Bind the UI elements to those two as appropiate, and then only change them in tandem (ie make them read-only externally, and have an internal process for updating the image+label that ensures you don't accidentally only update one but not the other).

tarepanda
Mar 26, 2011

Living the Dream
Oh, shoot. I've been using notifications all this time and didn't know/forgot what they were.

That's when you make an IBOutlet and connect it by right-click-dragging from the item to the IBOutlet, right?

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



The connection itself is called a binding. This causes the UI element to be an observer of the keypath (the property name) on your object. When you change a property with the setters, it will fire a notification and also tell any observers that stuff is changed. The observer then knows to update itself.

zergstain
Dec 15, 2005

Carthag posted:

Yes. Using either of the following ensures that notifications are posted. Also of course any additional logic you may have put in your setters/getters.

Objective-C code:
self.foo = bar;
//or (they're functionally equivalent)
[self setFoor:bar];
Using foo = bar will change an ivar (or even some local variable shadowing it) directly, no notifications.

Presumably you have @synthesize foo = foo; with an ivar called foo? You should avoid doing that (having the property and the ivar have identical names), it only creates confusion. In newer versions of XCode you can skip @synthesize altogether and it will synthesize to _foo.

You almost always want the notifications to fire. I generally only use direct access _foo = foo; in init methods before I return self.

I don't have any explicit ivars, just @property (strong) Foo *foo; in my .h and @synthesize foo; in my .m.

I was wondering why it worked when I forgot @synthesize. I guess the best thing to do is take all of them out so I get an error when I try to access foo directly?

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Deprecated versions synthesized foo to foo unless you explicitly wrote something else, so that's probably why it worked. Ie you were actually accessing the underlying ivar instead of the property, thus no notifications.

I've dropped writing out @synthesize in my own stuff. You still need @dynamic if you plan to have the getting/setting be handled at runtime.

zergstain
Dec 15, 2005

For custom getters and setters I guess I'm forced to use the _foo or self.foo notation, right?

Edit: Looks like self.foo also leads to infinite recursion. What are my options?

zergstain fucked around with this message at 18:46 on Sep 4, 2012

duck monster
Dec 15, 2004

I'm seeming to get some wierd poo poo going on with some string substitution.

code:
            NSPredicate *predicate = [NSPredicate predicateWithFormat:
                    @"(extras.pageids contains x%Dx ) and (fields.status <2)       ", del.contactId];
            self.sortedinbox = [self.inbox filteredArrayUsingPredicate:predicate];
            break;
I'm looking through a string for things like x235x or x543x (whatever the del.contactID number is).

The problem is, when I trap the code and dump the predicate to the console I just get

(extras.pageids contains x%Dx ) and (fields.status <2)

Whereas

code:
            NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                      @"(fields.owner = %D )  and (fields.status <2)", del.contactId];
            self.sortedinbox = [self.inbox filteredArrayUsingPredicate:predicate];
            break;
gives me

(fields.owner = 321 ) and (fields.status <2)

(or whatever the del.contactID is.

I can see where the problem is, that fugging string aint substituting, but I'm dumb and sleep deprived and not sure the syntax to fix it, and not quite getting the joy I'm looking for out of google.

Any suggestions?

edit: Regarding the x232x strings, its dealing with a lovely web service I didnt write with a fairly bonkers hack to get around limitations in a serializer that shits out stuff like;- pageids = "['x1x', 'x2x']"; Its a hack that works, but yeah.. wheeee.

duck monster fucked around with this message at 18:45 on Sep 4, 2012

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



duck monster posted:

I'm looking through a string for things like x235x or x543x (whatever the del.contactID number is).

Maybe use %@ in the predicate and create the x%Dx string yourself. I haven't worked with predicates in a while.

zergstain posted:

For custom getters and setters I guess I'm forced to use the _foo or self.foo notation, right?

Edit: Looks like self.foo also leads to infinite recursion. What are my options?

Don't use self.foo in a custom getter/setter. self.foo is translated to [self setFoo:] or [self foo] which obviously means it will keep recursing. In a custom setter/getter, you either use an instance variable (_foo) or whatever else makes sense (I often have readonly properties that basically just provide convenience access to whatever is inside your object, for instance a calculated property; the canonical example is r/o fullName which pieces together from r/w properties firstName & lastName).

Doctor w-rw-rw-
Jun 24, 2008

tarepanda posted:

Oh, shoot. I've been using notifications all this time and didn't know/forgot what they were.

That's when you make an IBOutlet and connect it by right-click-dragging from the item to the IBOutlet, right?

No.

fankey
Aug 31, 2001

I'm using TestFlightApp and have gotten a few crash reports. One of them contains the following call stack
code:
0 QSys UCI 0x000b4316 testflight_backtrace + 158
1 QSys UCI 0x000b4f40 TFSignalHandler + 244
2 libsystem_c.dylib 0x33b847ec _sigtramp + 48
3 CoreFoundation 0x312b8bee CFEqual + 106
4 CoreFoundation 0x312c1906 _CFAppVersionCheckLessThan + 50
5 CoreFoundation 0x312c183a +[NSArray allocWithZone:] + 82
6 Foundation 0x36d90dde -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] + 46
7 QSys UCI 0x000864b8 -[AppDelegate connectionStatusChanged:] + 72
8 Foundation 0x36e1c4fe __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 18
...
I've searched around and can't find anything about _CFAppVersionCheckLessThan. Any idea why something might be going haywire inside that function? I thought it might be related to the iOS version but the iPad is running 5.1.1 and my app is targeting 5.0.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Complete and total shot in the dark: is there an autorelease pool on your non-main thread?

fankey
Aug 31, 2001

pokeyman posted:

Complete and total shot in the dark: is there an autorelease pool on your non-main thread?
My code doesn't use any autorelease pools but I'm using a GDCAsyncSocket from CocoaAsyncSocket and that does use them internally.

In that particular call stack the Notification is called with the following code
code:
-(void)setStatus:(ConnectionState)state:(NSString*)message:(bool)isPrimary
{
  ConnectionStatus* status = [[ConnectionStatus alloc] init];
  status.state = state;
  status.message = message;
  status.isPrimary = isPrimary;
  [[NSNotificationCenter defaultCenter] postNotificationName: ConnectionStatusChangedNotification
                                                      object:status];
}
When using ARC do I need to do anything to make sure my status object isn't destroyed before the Notification takes place?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
NSNotificationCenter is synchronous, so you should be fine. I'm assuming the crash happens on the line with -postNotificationName:object:.

I'm wondering if the problem is further up the call stack. What does -[AppDelegate connectionStatusChanged:] do?

zergstain
Dec 15, 2005

Carthag posted:

Don't use self.foo in a custom getter/setter. self.foo is translated to [self setFoo:] or [self foo] which obviously means it will keep recursing. In a custom setter/getter, you either use an instance variable (_foo) or whatever else makes sense (I often have readonly properties that basically just provide convenience access to whatever is inside your object, for instance a calculated property; the canonical example is r/o fullName which pieces together from r/w properties firstName & lastName).

One last thing for now. I've been setting a property to readonly and providing a custom set method because I need special things to happen when it changes. The readonly removes the warnings. How wrong is this? I'm not 100% sure if I should just be using nonatomic.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



zergstain posted:

One last thing for now. I've been setting a property to readonly and providing a custom set method because I need special things to happen when it changes. The readonly removes the warnings. How wrong is this? I'm not 100% sure if I should just be using nonatomic.

You can cause observers & bindings to register a change like so:

Objective-C code:
[self willChangeValueForKey:@"foo"];
_foo = @"newValue"; //change ivar directly
[self didChangeValueForKey:@"foo"];
This is only necessary if you don't use the setter (-setFoo:... or self.foo = ...) to change it. Calling the setter will wrap it in will/didChange.

Generally, the easiest thing is to have a private read/write version of the property in a class extension, like this:

Objective-C code:
//***** ABObject.h *******
@interface ABObject : NSObject

-(void)doStuff;

@property (readonly) NSString *foo;

@end

//***** ABObject.m *******
@interface ABObject () //class extension

@property NSString *foo; //NOT readonly

@end

@implementation ABObject

-(void)doStuff
{
  self.foo = @"updated";
}

@end
That way you can use the property as read/write internally in your class, but externally it's read-only access.

See also: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html

zergstain
Dec 15, 2005

There actually is an external class which is calling setFoo, where foo is the property I have declared readonly. Seems the only effect that keyword has is to determine what methods get synthesized, so I get no complaints when I provide an implementation for setFoo.

The warning says I need to implement a getter if I implement a setter, or declare the property as nonatomic. Is there one of those that I should be doing, or does it matter?

Edit: I guess I could leave both methods synthesized and then register myself as an observer of my own key, and do the real work in my observeValueForKeyPath:ofObject:change:context, but that seems like I'd be over-engineering or something.

zergstain fucked around with this message at 03:34 on Sep 5, 2012

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

zergstain posted:

The warning says I need to implement a getter if I implement a setter, or declare the property as nonatomic. Is there one of those that I should be doing, or does it matter?

If you're giving either the getter or the setter a custom implementation, your class isn't really promising atomicity anymore, so you might as well make your property nonatomic. In general I would recommend making all of your properties nonatomic; it's really not a very useful feature, because atomicity on the level of a single field is very rarely a useful property of a class.

zergstain
Dec 15, 2005

rjmccall posted:

If you're giving either the getter or the setter a custom implementation, your class isn't really promising atomicity anymore, so you might as well make your property nonatomic. In general I would recommend making all of your properties nonatomic; it's really not a very useful feature, because atomicity on the level of a single field is very rarely a useful property of a class.

So why did Apple think it was?

Doc Block
Apr 15, 2003
Fun Shoe
AFAIK it just causes the compiler to use synthesized getters/setters that won't allow a property to be changed while it's being read. In other words, thread safety for that one property.

So it isn't a useless feature, but it doesn't make the whole class thread safe.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



zergstain posted:

There actually is an external class which is calling setFoo, where foo is the property I have declared readonly.

The atomicity part was answered but this seems to me like bad design. I don't know what you're trying to do, but it seems like you have a class whose property may only be changed a certain way/by a certain actor? It might be better to have the class with the property observe the external class (ie wait for notifications on a keypath), or have it be a delegate of it. Another way would be the data-source way; have the external object call -reloadData or similiar named method on your object, and the object will then go fetch what it needs. That way, you avoid relying on undocumented behavior (changing a property via a non-declared method).

Here's an example of a delegate (I'm away from my dev machine so untested):

Objective-C code:
#import <Foundation/Foundation.h>

// ***** delegate protocol ***** //
@protocol AAExternalDelegate

- (void)external:(id)external didUpdateFoo:(id)foo

@end

// ***** interfaces ***** //
@interface AAExternal : NSObject

-(void)triggerChange;

@property (weak) id<AAExternalDelegate> delegate;

@end

@interface AAObject<AAExternalDelegate> : NSObject

- (void)external:(id)external didUpdateFoo:(id)foo;

@property (readonly) id foo; //should not be changed from outside

@end

// ***** implementations ***** //
@implementation AAExternal

- (void)triggerChange
{
  [self.delegate external:self didUpdateFoo:@"newFooValue"];
}

@end

@interface AAObject () //class extension

@property id foo; //is read-write internally

@end

@implementation AAObject

- (void)external:(id)external didUpdateFoo:(id)foo
{
  self.foo = foo;
}

@end

// ***** let's try it out ***** //
int main( int argc, char **argv )
{
  AAObject *obj = [[AAObject alloc] init];
  AAExternal *ext = [[AAExternal alloc] init];
  
  NSLog(@"obj.foo: %@", obj.foo); //obj.foo is nil
  
  [ext setDelegate:obj];
  [ext triggerChange];
  
  NSLog(@"obj.foo: %@", obj.foo); //obj.foo is newFooValue
}

tarepanda
Mar 26, 2011

Living the Dream
I'm really confused. Sometimes my app will give an out of memory warning and crash, but when I check it in profiler, it's only using 3-6 MB at the time it crashes. What gives? What should I be looking for?

zergstain
Dec 15, 2005

Carthag posted:

The atomicity part was answered but this seems to me like bad design. I don't know what you're trying to do, but it seems like you have a class whose property may only be changed a certain way/by a certain actor? It might be better to have the class with the property observe the external class (ie wait for notifications on a keypath), or have it be a delegate of it. Another way would be the data-source way; have the external object call -reloadData or similiar named method on your object, and the object will then go fetch what it needs. That way, you avoid relying on undocumented behavior (changing a property via a non-declared method).

Nah, I was just totally abusing the readonly specifier. I made it (and everything else) nonatomic.

Anyway, I also have an NSView which has a rectangle that follows the cursor (sort of, it's on a grid). How can I make it so when I scroll the view, this rectangle stays with the cursor? It of course jumps to where it's supposed to be when a mouseMoved event is received.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



This might work, but there's probably a better way:

Objective-C code:
@interface MyUpdatingScrollView : NSScrollView

@end

@implementation MyUpdatingScrollView

- (void)reflectScrolledClipView:(NSClipView *)aClipView //invoked automatically during scrolling, see docs
{
  NSPoint mouseLoc = [NSEvent mouseLocation];
  
  //do whatever
  
  [super reflectScrolledClipView:aClipView];
}

@end

fankey
Aug 31, 2001

pokeyman posted:

NSNotificationCenter is synchronous, so you should be fine. I'm assuming the crash happens on the line with -postNotificationName:object:.

I'm wondering if the problem is further up the call stack. What does -[AppDelegate connectionStatusChanged:] do?

Here's the entire call stack. I've posted the functions in the call stack relative to my code here.
code:
0 QSys UCI 0x000b4316 testflight_backtrace + 158
1 QSys UCI 0x000b4f40 TFSignalHandler + 244
2 libsystem_c.dylib 0x33b847ec _sigtramp + 48
3 CoreFoundation 0x312b8bee CFEqual + 106
4 CoreFoundation 0x312c1906 _CFAppVersionCheckLessThan + 50
5 CoreFoundation 0x312c183a +[NSArray allocWithZone:] + 82
6 Foundation 0x36d90dde -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] + 46
7 QSys UCI 0x000864b8 -[AppDelegate connectionStatusChanged:] + 72
8 Foundation 0x36e1c4fe __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 18
9 CoreFoundation 0x3133b546 ___CFXNotificationPost_block_invoke_0 + 70
10 CoreFoundation 0x312c7096 _CFXNotificationPost + 1406
11 Foundation 0x36d903ea -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
12 Foundation 0x36d91c1a -[NSNotificationCenter postNotificationName:object:] + 30
13 QSys UCI 0x0009a3e4 -[RemoteConnection setStatus:::] + 204
14 QSys UCI 0x0009a588 -[RemoteConnection statusTimer:] + 308
15 Foundation 0x36e3260c __NSFireTimer + 144
16 CoreFoundation 0x31343a32 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
17 CoreFoundation 0x31343698 __CFRunLoopDoTimer + 364
18 CoreFoundation 0x3134226e __CFRunLoopRun + 1206
19 CoreFoundation 0x312c54a4 CFRunLoopRunSpecific + 300
20 CoreFoundation 0x312c536c CFRunLoopRunInMode + 104
21 GraphicsServices 0x3279e438 GSEventRunModal + 136
22 UIKit 0x315cacd4 UIApplicationMain + 1080
23 QSys UCI 0x00078d2e main + 26
24 QSys UCI 0x00078d0f start + 39

fankey
Aug 31, 2001

So it looks like at least part of my problem was calling std::string( [someNSString UTF8String] ) when someNSString == nil. When using lldb as my debugger I would get crazy call stacks when the exception was thrown. If I switch back to gdb I get a nice obvious call stack which showed me the problem in about 6 seconds. Is this expected behavior for lldb? Anything I can do to make it work better? Or should I just use gdb until lldb becomes more robust?

zergstain
Dec 15, 2005

Carthag posted:

This might work, but there's probably a better way:

Objective-C code:
@interface MyUpdatingScrollView : NSScrollView

@end

@implementation MyUpdatingScrollView

- (void)reflectScrolledClipView:(NSClipView *)aClipView //invoked automatically during scrolling, see docs
{
  NSPoint mouseLoc = [NSEvent mouseLocation];
  
  //do whatever
  
  [super reflectScrolledClipView:aClipView];
}

@end

Of course, the view I need to update is the NSScrollView's document view. So if there's some message that gets sent to that view, or a notification I can register for, that would be preferable to subclassing NSScrollView for one method.

lord funk
Feb 16, 2004

Ender.uNF posted:

My icon never looks right until the update goes live.

Well the update has gone live, and on the store my app has the glossy effect. While you download, it has the glossy effect. And only after it's completed downloading does the effect go away. Sigh.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

zergstain posted:

So why did Apple think it was?

This was before my time, but in many ways it's a safer default if you think of properties as being primarily about external API. If you think of properties as the main way you get storage in an object, which is what they've become, it's an unfortunate choice.

Doc Block
Apr 15, 2003
Fun Shoe

lord funk posted:

Well the update has gone live, and on the store my app has the glossy effect. While you download, it has the glossy effect. And only after it's completed downloading does the effect go away. Sigh.

See my post earlier about this.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

fankey posted:

Here's the entire call stack. I've posted the functions in the call stack relative to my code here.

I don't think you posted what the crash is exactly. Exception? Segfault?

Looking at your code, I don't see anything odd. I think your best bet is to reduce it to a small test case and come on back.

Adbot
ADBOT LOVES YOU

zergstain
Dec 15, 2005

I don't know what could've changed, but I'm trying to observe the selectionIndex key of an NSArraryController, and it's stopped working. The change dictionary new key object is always NSNull, and when I print the value for the key path in the debugger console, I get 0xc7. The key is NSUInteger, but I thought scalars got wrapped inside an NSNumber. That is neither a valid object address, nor a valid integer selection index. Any ideas for things to try?

Edit: I forgot to mention I have NSTableColumns bound to different model keys in arrangedObjects. The NSTableView itself isn't bound to anything, and the NSArrayController's selectionIndexes isn't bound to anything either. I've tried playing around with it, but no luck.

zergstain fucked around with this message at 02:57 on Sep 7, 2012

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply