Date   

Re: Some advice requested on debugging a difficult problem. iOS.

 



On Mar 26, 2019, at 8:53 AM, Alex Zavatone via Groups.Io <zav@...> wrote:

@property(strong, nonatomic, readwrite,getter=getRootAPIData) NSDictionary *rootUrlMap;

See how we have an accessor defined for rootUrlMap to be getRootAPIData?  (Yes, that get is bad form, i know.)

At the runtime level, properties are implemented as getter and/or setter methods. The `getter=` syntax just lets you rename the getter method. It doesn’t affect the property name.

It seems a little weird that you can use the custom getter method name with property syntax; I guess that’s just because for backward-compatibility reasons Obj-C lets you call any no-arguments method using “.” syntax (if it has a non-void return type.)

I can’t imagine how this would cause any weird results like you’re getting. You get exactly the same compiled code, whichever name you use to access the property.

—Jens


Re: Some advice requested on debugging a difficult problem. iOS.

Alex Zavatone
 

I just replicated this in a sample and ran a short test to see what the results are.  

@interface MyObject : NSObject

@property(strong, nonatomic, readwrite,getter=getRootAPIData) NSDictionary *rootUrlMap;

@end



@implementation MyObject

- (id)init {
    if (self == [super init]) {
        _rootUrlMap = [NSDictionary dictionaryWithObjectsAndKeys:@"Hi",@"myKey", nil];
    }
    return self;
}

@end



    MyObject *myObject = [MyObject new];

    

    NSLog(@"%@", myObject.rootUrlMap);
    NSLog(@"%@", myObject.getRootAPIData);
    NSLog(@"%@", [myObject getRootAPIData]);


2019-03-26 11:01:30.116353-0500 Test[80252:7074112] {
    myKey = Hi;
}
2019-03-26 11:01:30.116528-0500 Test[80252:7074112] {
    myKey = Hi;
}
2019-03-26 11:01:30.116654-0500 Test[80252:7074112] {
    myKey = Hi;
}

So, the getter and the property name both allow accessing the property.

But should we expect it to if the getter has been redefined?

Thanks again.
Alex Zavatone


On Mar 26, 2019, at 10:53 AM, Alex Zavatone via Groups.Io <zav@...> wrote:

In the iOS app that I’m working on now, we have a problem that I’ve never seen in my years as an iOS programmer.

While we have a 99.7% crash free user experience, what does crash is weird as fuck.

By that, I mean that data that normally exists in a dictionary most of the time suddenly becomes nil.

It was today when I noticed this.

@property(strong, nonatomic, readwrite,getter=getRootAPIData) NSDictionary *rootUrlMap;

See how we have an accessor defined for rootUrlMap to be getRootAPIData?  (Yes, that get is bad form, i know.)

Well, we never use it.

We always access it like so, [AppEnvironment sharedEnvironment].appContext.rootUrlMap;

And there is only one instance of getRootAPIData in the app… where it is defined.

And here’s my question.  Would directly accessing the property via the property name, even when its getter is defined to be something else, would this occasionally result in a nil return?

So, what happens when you define a getter of an object’s property to be something else, yet still try to get a value from the name of the property?


We have a lot of sloppy programming, including a lot of the hacky safeObjectForKey: to prevent crashing when accessing a value from a dictionary when you assume that the dictionary is not nil and I’m trying to sort out all this slop.

Thanks in advance,
Alex Zavatone




Some advice requested on debugging a difficult problem. iOS.

Alex Zavatone
 

In the iOS app that I’m working on now, we have a problem that I’ve never seen in my years as an iOS programmer.

While we have a 99.7% crash free user experience, what does crash is weird as fuck.

By that, I mean that data that normally exists in a dictionary most of the time suddenly becomes nil.

It was today when I noticed this.

@property(strong, nonatomic, readwrite,getter=getRootAPIData) NSDictionary *rootUrlMap;

See how we have an accessor defined for rootUrlMap to be getRootAPIData? (Yes, that get is bad form, i know.)

Well, we never use it.

We always access it like so, [AppEnvironment sharedEnvironment].appContext.rootUrlMap;

And there is only one instance of getRootAPIData in the app… where it is defined.

And here’s my question. Would directly accessing the property via the property name, even when its getter is defined to be something else, would this occasionally result in a nil return?

So, what happens when you define a getter of an object’s property to be something else, yet still try to get a value from the name of the property?


We have a lot of sloppy programming, including a lot of the hacky safeObjectForKey: to prevent crashing when accessing a value from a dictionary when you assume that the dictionary is not nil and I’m trying to sort out all this slop.

Thanks in advance,
Alex Zavatone


Re: find standard about panel

James Walker
 

On Mar 13, 2019, at 8:01 PM, Jon Gotow <gotow@...> wrote:

Well, its class is NSPanel rather than NSWindow - is it sufficient to just hide / show all NSPanels in the app's window list when you're deactivated / activated?

Alternately, you can look at all NSPanels and see if any have an NSTextField subview that has a string value equal to the localized name of your app (which you can just grab from NSApp.accessibilityLabel if you don't want to screw around with NSBundle). That's almost certain to be the About box unless you're putting your app's name in a text control in one of your windows :-) Not pretty, but it'd work without too much overhead.
There are other NSPanels, that’s not sufficient.

What I came up with was to find an array of visible windows before calling orderFrontStandardAboutPanel:, find an array of visible windows afterward, and whatever’s in the second list but not the first must be the About panel.


Re: find standard about panel

James Walker
 

On Mar 13, 2019, at 8:07 PM, Graham Cox <graham@...> wrote:

How hard is it then to make your own About box? To bring it up instead of the prebuilt one is a very small change to the ‘About’ menu item, to target a different method.

Making your own About box is part of polishing your app anyway, in most cases.
True, but this is a little freeware side project, and I didn’t feel like polishing that much.


Re: Custom UTIs based on com.apple.package don't always work

Steve Mills
 

On Mar 14, 2019, at 01:03:16, Quincey Morris <quinceymorris@...> wrote:

Well, this is kind of wrong. CFBundleTypeExtensions and LSTypeIsPackage should not be specified in the document type when you’re using an exported UTI.
Where is it documented that it's wrong? I don't think it's actually wrong. iMovie, for example, has com.apple.iMovieEvent declared both as an exported UTI and as a document type. Besides, it *does* work when the app is in /Applications.

I don’t really recall their presence actively messing things up, but I suggest you get rid of them. AFAICT, the most complete and accurate documentation is this:

https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-101685-TPXREF107

and you have to read Table 2 carefully to see what doesn’t apply any more (i.e. since 10.5!).
Yes, deprecated keys don't actually mess things up though when newer ones take precedence.

When I sync and run it on mac 10.14 Mac …
What does “sync” mean in this context? Is Xcode running on the 10.14 Mac, or is it running on a 10.13 Mac? Are you doing some kind of command line copy to move the bundle between Macs?
Sync my source from the repo. Some might only know the phrase "pull my changes from the server" if they haven't used SCMs other than svn or git. Having cut my teeth on Perforce and used it for the first 15 years of my career, I'll probably never stop using the term "sync" for this.

--
Steve Mills
Drummer, Mac geek


Re: Custom UTIs based on com.apple.package don't always work

Quincey Morris
 

On Mar 13, 2019, at 21:17 , Steve Mills via Groups.Io <sjmills@...> wrote:

<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>livery</string>
</array>
<key>CFBundleTypeName</key>
<string>Livery</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).livery</string>
</array>
<key>LSTypeIsPackage</key>
<integer>1</integer>
</dict>
</array>

Well, this is kind of wrong. CFBundleTypeExtensions and LSTypeIsPackage should not be specified in the document type when you’re using an exported UTI. I don’t really recall their presence actively messing things up, but I suggest you get rid of them. AFAICT, the most complete and accurate documentation is this:


and you have to read Table 2 carefully to see what doesn’t apply any more (i.e. since 10.5!).

When I sync and run it on mac 10.14 Mac …

What does “sync” mean in this context? Is Xcode running on the 10.14 Mac, or is it running on a 10.13 Mac? Are you doing some kind of command line copy to move the bundle between Macs?


Custom UTIs based on com.apple.package don't always work

Steve Mills
 

I have a file type all set up in my target's Document Types and Exported UTIs as so:

<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>livery</string>
</array>
<key>CFBundleTypeName</key>
<string>Livery</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).livery</string>
</array>
<key>LSTypeIsPackage</key>
<integer>1</integer>
</dict>
</array>

<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>com.apple.package</string>
</array>
<key>UTTypeDescription</key>
<string>Livery</string>
<key>UTTypeIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).livery</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>livery</string>
</array>
</dict>
</dict>
</array>

It always work on the Macs where I've done most of the development work, which started on 10.10 and is now 10.13. When I sync and run it on mac 10.14 Mac, the files never work because [url getResourceValue:&type forKey:NSURLTypeIdentifierKey error:nil] says it's a public.folder instead of my declared UTI. I can make it work by copying the app into /Applications and running it from there. From then it will work when running from Xcode. But as soon as I delete the app from /Applictions and then run from Xcode again, it goes back to thinking it's public.folder.

Why doesn't this work like it should? And by that I mean that if one is developing an app that has custom UTIs, they should *work* during development. I could just leave a copy in /Applications, but I shouldn't have to.

--
Steve Mills
Drummer, Mac geek


Re: find standard about panel

Jack Brindle
 

The About window has no name - the title is blank.

it would seem that a more interesting way to do the would be to use the [NSWindow windowNumberWithOptions:] method, which does return an array of windows for the app (options = 0) that is ordered in a front to back order. Since you are getting an array of windows you should be able to apply any test you wish too them.

There are other methods, such as [NSApplication windows] that will also give you an array of all application windows, shown or not, but they are not ordered.

Jack

On Mar 13, 2019, at 8:01 PM, Jon Gotow <gotow@...> wrote:

Well, its class is NSPanel rather than NSWindow - is it sufficient to just hide / show all NSPanels in the app's window list when you're deactivated / activated?

Alternately, you can look at all NSPanels and see if any have an NSTextField subview that has a string value equal to the localized name of your app (which you can just grab from NSApp.accessibilityLabel if you don't want to screw around with NSBundle). That's almost certain to be the About box unless you're putting your app's name in a text control in one of your windows :-) Not pretty, but it'd work without too much overhead.

- Jon


On 14 Mar 2019, at 8:41 am, James Walker <list2@...> wrote:

How can I find the window produced by -[NSApplication
orderFrontStandardAboutPanel:]? (I’d like to hide the window when my app deactivates.) I know it’s somewhere in the array -[NSApplication windows], but I don’t know how to identify which one.



Re: find standard about panel

Graham Cox
 



On 14 Mar 2019, at 1:32 pm, Graham Cox <graham.cox@...> wrote:



On 14 Mar 2019, at 11:04 am, James Walker <list2@...> wrote:

The standard About panel doesn’t exist in a nib, it’s synthesized by AppKit.


Ah, fair point!

How hard is it then to make your own About box? To bring it up instead of the prebuilt one is a very small change to the ‘About’ menu item, to target a different method.

Making your own About box is part of polishing your app anyway, in most cases.

—G


Re: find standard about panel

Jon Gotow
 

Well, its class is NSPanel rather than NSWindow - is it sufficient to just hide / show all NSPanels in the app's window list when you're deactivated / activated?

Alternately, you can look at all NSPanels and see if any have an NSTextField subview that has a string value equal to the localized name of your app (which you can just grab from NSApp.accessibilityLabel if you don't want to screw around with NSBundle). That's almost certain to be the About box unless you're putting your app's name in a text control in one of your windows :-) Not pretty, but it'd work without too much overhead.

- Jon

On 14 Mar 2019, at 8:41 am, James Walker <list2@...> wrote:

How can I find the window produced by -[NSApplication
orderFrontStandardAboutPanel:]? (I’d like to hide the window when my app deactivates.) I know it’s somewhere in the array -[NSApplication windows], but I don’t know how to identify which one.


Re: find standard about panel

James Walker
 

On Mar 13, 2019, at 4:35 PM, Graham Cox <graham@...> wrote:

In Interface Builder, just check the “Hides on Deactivate” checkbox for the panel. That should do it… have you tried it?
The standard About panel doesn’t exist in a nib, it’s synthesized by AppKit.


—G

On 14 Mar 2019, at 8:41 am, James Walker <list2@...> wrote:

How can I find the window produced by -[NSApplication
orderFrontStandardAboutPanel:]? (I’d like to hide the window when my app deactivates.) I know it’s somewhere in the array -[NSApplication windows], but I don’t know how to identify which one.


Re: find standard about panel

Graham Cox
 

In Interface Builder, just check the “Hides on Deactivate” checkbox for the panel. That should do it… have you tried it?

—G

On 14 Mar 2019, at 8:41 am, James Walker <list2@...> wrote:

How can I find the window produced by -[NSApplication
orderFrontStandardAboutPanel:]?  (I’d like to hide the window when my app deactivates.)  I know it’s somewhere in the array -[NSApplication windows], but I don’t know how to identify which one.


find standard about panel

James Walker
 

How can I find the window produced by -[NSApplication
orderFrontStandardAboutPanel:]?  (I’d like to hide the window when my app deactivates.)  I know it’s somewhere in the array -[NSApplication windows], but I don’t know how to identify which one.


Re: Care to opine on a stack trace

Sandor Szatmari
 

Jens,

On Mar 13, 2019, at 14:13, Jens Alfke <jens@...> wrote:



On Mar 13, 2019, at 11:06 AM, Sandor Szatmari <admin.szatmari.net@...> wrote:

I’m not experienced with putting these pieces together… can this be determined from the crash report?  Or, do I need to determine this when a crash actually occurs?

It’s in the crash report near the top, like this:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000

That long hex number is the address.

Thanks here’s what I have,

Exception Type:        EXC_BREAKPOINT (SIGTRAP)
Exception Codes:       0x0000000000000002, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
*** CFHash() called with NULL ***


—Jens


Re: Care to opine on a stack trace

 



On Mar 13, 2019, at 11:06 AM, Sandor Szatmari <admin.szatmari.net@...> wrote:

I’m not experienced with putting these pieces together… can this be determined from the crash report?  Or, do I need to determine this when a crash actually occurs?

It’s in the crash report near the top, like this:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000

That long hex number is the address.

—Jens


Re: Care to opine on a stack trace

Sandor Szatmari
 

Jens,

On Mar 13, 2019, at 13:57, Jens Alfke <jens@...> wrote:



On Mar 13, 2019, at 8:16 AM, Sandor Szatmari <admin.szatmari.net@...> wrote:

I have an app where I see this crash periodically. Does this look to you like the stream is being destroyed before the run loop releases it? Basically an overrelease?
Not exactly. In frame 4 the NSInputStream has been messaged successfully, which almost never happens if it’s already dealloced; you almost always get a crash in objc_msgsend in that case.
Thanks for pointing out this out. That makes sense since presumably in the frames above we are in calls resulting from the stream removing itself which would be hard to explain if it were dealloc’d. Is this the right conclusion?


Instead it looks like something’s wrong with a dictionary managed by the stream. I don’t know exactly what.
Thanks for pointing me in a direction.


What’s the offending memory address in the crash? If it’s zero, that could be a clue.
I’m not experienced with putting these pieces together… can this be determined from the crash report? Or, do I need to determine this when a crash actually occurs?

Can you run the app with NSZombie enabled until the crash reoccurs?
I can and will…

Thanks,
Sandor


—Jens


Re: Care to opine on a stack trace

 

On Mar 13, 2019, at 8:16 AM, Sandor Szatmari <admin.szatmari.net@...> wrote:

I have an app where I see this crash periodically. Does this look to you like the stream is being destroyed before the run loop releases it? Basically an overrelease?
Not exactly. In frame 4 the NSInputStream has been messaged successfully, which almost never happens if it’s already dealloced; you almost always get a crash in objc_msgsend in that case.

Instead it looks like something’s wrong with a dictionary managed by the stream. I don’t know exactly what.

What’s the offending memory address in the crash? If it’s zero, that could be a clue.
Can you run the app with NSZombie enabled until the crash reoccurs?

—Jens


Care to opine on a stack trace

Sandor Szatmari
 

I have an app where I see this crash periodically. Does this look to you like the stream is being destroyed before the run loop releases it? Basically an overrelease?


Thread 8 Crashed:
0 com.apple.CoreFoundation 0x9a462ce8 CFHash + 200
1 com.apple.CoreFoundation 0x9a465bc2 CFBasicHashFindBucket + 514
2 com.apple.CoreFoundation 0x9a46596b CFDictionaryGetValue + 123
3 com.apple.CoreFoundation 0x9a52fe82 _CFStreamUnscheduleFromRunLoop + 194
4 com.apple.CoreFoundation 0x9a59237d -[__NSCFInputStream removeFromRunLoop:forMode:] + 61
5 net.infoplus.downloader 0x00050544 -[ServerConnectionHandler handleNewServerConnection:] + 1038
6 com.apple.Foundation 0x9b0554d7 -[NSThread main] + 45
7 com.apple.Foundation 0x9b055262 __NSThread__start__ + 1550
8 libsystem_pthread.dylib 0x9bff9780 _pthread_body + 138
9 libsystem_pthread.dylib 0x9bff96f6 _pthread_start + 155
10 libsystem_pthread.dylib 0x9bff6f7a thread_start + 34


Sandor


Re: Continuously update value bug in 10.13

Steve Mills
 

On Mar 2, 2019, at 19:39:00, Alex Zavatone via Groups.Io <zav@...> wrote:

IIRC, there is another method that you can check, with something like didEndEditing something like that.

I remember having to go through several on iOS to find what I wanted.
I stopped on that breakpoint as well, and it doesn't help other than point out that it is indeed a bug. Changing the bound value should not cause editing to end. I just want to know if it's been fixed since 10.13.

--
Steve Mills
Drummer, Mac geek

581 - 600 of 1475