Re: Retrieving the EXIF date/time from 250k images

2023-01-08 Thread Chris Ridd via Cocoa-dev


> On 7 Jan 2023, at 23:31, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
>> 
>> I wonder if there is a method to load the EXIF data out of the files without 
>> opening them completely.  That would seem like the ideal approach.
> 
> That's the approach I am looking for, but I haven't found any API to do that.

I’m sure you’ve tried the following, but in case you haven’t:

* investigate mmapping each file into memory and use a version of the API that 
takes NSData/CFData instead of a file/URL to get the EXIF information. 

* if the files are indexed by Spotlight, can you get the EXIF information from 
a NSMetadataQuery search?

Chris
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


NSCollectionView, disappearing items on reloadData

2023-01-08 Thread Arved von Brasch via Cocoa-dev
Hello list,

I’ve encountered a bug for the life of me I can’t work out. I’m restricted to 
supporting Mojave (10.14) for the time being, so it is possible this has been 
fixed / not an issue on later releases. This is a Core Data backed application, 
with several Xib loaded views that are swapped in and out based on the 
selection of a segmented control in the toolbar. The basic issue is that when I 
call ‘reloadData()’ on a CollectionView, all the items disappear (this 
typically happens if the user switches to a different view and then back again, 
as, while previously loaded views are kept in memory, they are reloaded upon 
switching back to the foreground - ie. this is not tabs, but separate loads of 
Xib file Views). If I put a break point in an override of ‘viewWillDisappear()` 
in my NSCollectionViewItem subclass, I can see the backtrace indicates that 
NSCollectionView has decided to reuse the CollectionViewItem but not issued a 
new one:

* NSCollectionView reloadData
* _NSCollectionViewCore reloadData
* _NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:
* __35-_NSCollectionViewCore reloadData]_block_invoke
* NSCollectionViewCore _reuseCell:notifyDidEndDisplaying:
* _reuseViewWithReuseQueue
* NSCollectionViewItem _setHiddenForReuse:
* NSView(NSInternal) _setHidden:setNeedsDisplay:
* NSView _recursiveViewWillDisappearBeacuseHidden
* NSViewController _sendViewWillDisappear
* @objc CollectionViewItem.viewWillDisappear()
* CollectionViewItem.viewWillDisappear()

In the NSCollectionView itself, I can see the items are removed from the 
‘visibleItems()’ array, but the items themselves still seems to be known about 
by the collection view, as they will remain in the ‘selectionIndexPaths:’ if 
they were previously selected.

What’s really weird is that because we have multiple top level views, a lot of 
the code is reused on different displays, including the NSArrayController 
subclass that serves as the Delegate and DataSource for this NSCollectionView. 
It works perfectly fine in the other case. The main difference between these 
two top levels views, is that in the one that works, the Collection View is 
slaved to a Table View (ie the collection view shows the items in a 
relationship to the selection in the table view), where as in the one that 
doesn’t work, the behaviour is inverted (the selection in the collection view 
is the data source for a slaved table view). To be clear, though, both are 
displaying completely different Core Data entities. I don’t think I’ve missed 
anything, so as far as I can tell both NSCollectionViews are configured 
identically in the two XIBs.

The last weird thing is that the problem only seems to manifest if the 
application has previously been built. If I Make Clean first, the resulting 
behaviour is as I would expect. If I close and reopen the application, the 
behaviour is then broken. The backtrace is common to both situations, so the 
problem is that something is preventing the Collection View from reissuing a 
CollectionViewItem for the objects. I’m not sure where to look for that side, 
other than to say that ‘viewWillAppear()’ is not called when the problem is 
occurring, and does when it isn't.

I’m fairly convinced that the problem is in the Xib file. I have tried removing 
everything else except the NSCollectionView and a few buttons and the problem 
doesn’t seem to manifest in that case. I haven’t tried bringing in one 
additional view or controller at a time to see when it eventually breaks, 
because there are far too many for that to be a good debugging path. The view 
with the working CollectionView is significantly simpler, if that matters. (I 
suppose a solution could be to take the Collection View out into its own Xib 
file and load into the view manually, or create it programatically, neither of 
which is particularly attractive.) Doing a side-by-side comparison of the 
configuration of Collection View in each Xib file and associated Controllers 
only shows expected differences (e.g. entities and spacing sizes).

I’ve been banging my head agains this for several days now, so would appreciate 
any guidance towards a solution,

Arved

P.S. The code is fairly straightforward, I think:

class FlowLayout: NSCollectionViewFlowLayout {

   init(withSize size: NSSize, edge: CGFloat, spacing: CGFloat) {
   super.init()
   itemSize = size
   estimatedItemSize = NSZeroSize
   sectionInset = NSEdgeInsetsMake(edge, edge, edge, edge)
   minimumInteritemSpacing = spacing
   minimumLineSpacing = spacing
   }

   override func layoutAttributesForElements(in rect: NSRect) -> 
[NSCollectionViewLayoutAttributes] {
   // Excluded for brevity
   return leftAlignedAttributes
   }

   override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> 
Bool {
   return true
   }

}

class CollectionViewItem: NSCollectionViewItem {

   fileprivate var prefSize: NSSize

   required override init(nibName nibNameOrNil: 

Re: NSCollectionView, disappearing items on reloadData

2023-01-08 Thread Rob Petrovec via Cocoa-dev
NSCollectionView, like NSTableView/NSOutlineView, will reuse existing views 
instead of recreating them when it can to speed up the UI. This is most 
commonly used during scrolling where views that scroll out of view will be 
reused with new data and scrolled into view. It will call -prepareForReuse (See 
NSCollectionVIewElement protocol) on the NSCollectionViewItem (and I think the 
view too) so you can reset them back to their post -init state.  I’d look into 
implementing that and see if that helps.

Also, -reloadData will trigger a series of NSCollectionViewDelegate methods to 
be called which will dictate what appears in the view after reload.  Set some 
breakpoints in -collectionView:numberOfItemsInSection: & 
-collectionView:itemForRepresentedObjectAtIndexPath: and make sure you are 
returning expected values.

With that said, -reloadData is a pretty big hammer and can kill performance 
with large view hierarchies. It’s better to use API like 
-performBatchUpdates:completionHandler: and related methods to 
insert/move/remove views as needed.

Hope that helps & good luck.

—Rob


> On Jan 8, 2023, at 2:03 PM, Arved von Brasch via Cocoa-dev 
>  wrote:
> 
> Hello list,
> 
> I’ve encountered a bug for the life of me I can’t work out. I’m restricted to 
> supporting Mojave (10.14) for the time being, so it is possible this has been 
> fixed / not an issue on later releases. This is a Core Data backed 
> application, with several Xib loaded views that are swapped in and out based 
> on the selection of a segmented control in the toolbar. The basic issue is 
> that when I call ‘reloadData()’ on a CollectionView, all the items disappear 
> (this typically happens if the user switches to a different view and then 
> back again, as, while previously loaded views are kept in memory, they are 
> reloaded upon switching back to the foreground - ie. this is not tabs, but 
> separate loads of Xib file Views). If I put a break point in an override of 
> ‘viewWillDisappear()` in my NSCollectionViewItem subclass, I can see the 
> backtrace indicates that NSCollectionView has decided to reuse the 
> CollectionViewItem but not issued a new one:
> 
> * NSCollectionView reloadData
> * _NSCollectionViewCore reloadData
> * _NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:
> * __35-_NSCollectionViewCore reloadData]_block_invoke
> * NSCollectionViewCore _reuseCell:notifyDidEndDisplaying:
> * _reuseViewWithReuseQueue
> * NSCollectionViewItem _setHiddenForReuse:
> * NSView(NSInternal) _setHidden:setNeedsDisplay:
> * NSView _recursiveViewWillDisappearBeacuseHidden
> * NSViewController _sendViewWillDisappear
> * @objc CollectionViewItem.viewWillDisappear()
> * CollectionViewItem.viewWillDisappear()
> 
> In the NSCollectionView itself, I can see the items are removed from the 
> ‘visibleItems()’ array, but the items themselves still seems to be known 
> about by the collection view, as they will remain in the 
> ‘selectionIndexPaths:’ if they were previously selected.
> 
> What’s really weird is that because we have multiple top level views, a lot 
> of the code is reused on different displays, including the NSArrayController 
> subclass that serves as the Delegate and DataSource for this 
> NSCollectionView. It works perfectly fine in the other case. The main 
> difference between these two top levels views, is that in the one that works, 
> the Collection View is slaved to a Table View (ie the collection view shows 
> the items in a relationship to the selection in the table view), where as in 
> the one that doesn’t work, the behaviour is inverted (the selection in the 
> collection view is the data source for a slaved table view). To be clear, 
> though, both are displaying completely different Core Data entities. I don’t 
> think I’ve missed anything, so as far as I can tell both NSCollectionViews 
> are configured identically in the two XIBs.
> 
> The last weird thing is that the problem only seems to manifest if the 
> application has previously been built. If I Make Clean first, the resulting 
> behaviour is as I would expect. If I close and reopen the application, the 
> behaviour is then broken. The backtrace is common to both situations, so the 
> problem is that something is preventing the Collection View from reissuing a 
> CollectionViewItem for the objects. I’m not sure where to look for that side, 
> other than to say that ‘viewWillAppear()’ is not called when the problem is 
> occurring, and does when it isn't.
> 
> I’m fairly convinced that the problem is in the Xib file. I have tried 
> removing everything else except the NSCollectionView and a few buttons and 
> the problem doesn’t seem to manifest in that case. I haven’t tried bringing 
> in one additional view or controller at a time to see when it eventually 
> breaks, because there are far too many for that to be a good debugging path. 
> The view with the working CollectionView is significantly simpler, if that 
> matters. (I suppose a 

Re: NSCollectionView, disappearing items on reloadData

2023-01-08 Thread Arved von Brasch via Cocoa-dev
Thanks Rob. I can confirm that ‘prepareForReuse()’ is *not* called after the 
‘reloadData()’ call. I can also confirm the Data Source functions still contain 
the expected information. Again, this is an interesting case where the working 
Collection View behaves as expected (prepareForReuse() is called), but the 
non-working one does not.

In the non-working case, after reloadData(), the Collection View calls 
numberOfSections: (returns hardcoded 1) then 
collectionView:NumberOfItemsInSection: (which returns 1 in the test case I did 
just now), but there is no subsequent call of 
collectionView:itemForRepresentedObjectAt:.

Yes, there’s a lot of scope for further improvement. For the time being, the 
easiest solution is to reload / refresh all views when the user switches tabs.

Cheers,
Arved


> On 09 Jan 2023, at 08:31, Rob Petrovec  wrote:
> 
> NSCollectionView, like NSTableView/NSOutlineView, will reuse existing views 
> instead of recreating them when it can to speed up the UI. This is most 
> commonly used during scrolling where views that scroll out of view will be 
> reused with new data and scrolled into view. It will call -prepareForReuse 
> (See NSCollectionVIewElement protocol) on the NSCollectionViewItem (and I 
> think the view too) so you can reset them back to their post -init state.  
> I’d look into implementing that and see if that helps.
> 
> Also, -reloadData will trigger a series of NSCollectionViewDelegate methods 
> to be called which will dictate what appears in the view after reload.  Set 
> some breakpoints in -collectionView:numberOfItemsInSection: & 
> -collectionView:itemForRepresentedObjectAtIndexPath: and make sure you are 
> returning expected values.
> 
> With that said, -reloadData is a pretty big hammer and can kill performance 
> with large view hierarchies. It’s better to use API like 
> -performBatchUpdates:completionHandler: and related methods to 
> insert/move/remove views as needed.
> 
> Hope that helps & good luck.
> 
> —Rob
> 
> 
>> On Jan 8, 2023, at 2:03 PM, Arved von Brasch via Cocoa-dev 
>>  wrote:
>> 
>> Hello list,
>> 
>> I’ve encountered a bug for the life of me I can’t work out. I’m restricted 
>> to supporting Mojave (10.14) for the time being, so it is possible this has 
>> been fixed / not an issue on later releases. This is a Core Data backed 
>> application, with several Xib loaded views that are swapped in and out based 
>> on the selection of a segmented control in the toolbar. The basic issue is 
>> that when I call ‘reloadData()’ on a CollectionView, all the items disappear 
>> (this typically happens if the user switches to a different view and then 
>> back again, as, while previously loaded views are kept in memory, they are 
>> reloaded upon switching back to the foreground - ie. this is not tabs, but 
>> separate loads of Xib file Views). If I put a break point in an override of 
>> ‘viewWillDisappear()` in my NSCollectionViewItem subclass, I can see the 
>> backtrace indicates that NSCollectionView has decided to reuse the 
>> CollectionViewItem but not issued a new one:
>> 
>> * NSCollectionView reloadData
>> * _NSCollectionViewCore reloadData
>> * _NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:
>> * __35-_NSCollectionViewCore reloadData]_block_invoke
>> * NSCollectionViewCore _reuseCell:notifyDidEndDisplaying:
>> * _reuseViewWithReuseQueue
>> * NSCollectionViewItem _setHiddenForReuse:
>> * NSView(NSInternal) _setHidden:setNeedsDisplay:
>> * NSView _recursiveViewWillDisappearBeacuseHidden
>> * NSViewController _sendViewWillDisappear
>> * @objc CollectionViewItem.viewWillDisappear()
>> * CollectionViewItem.viewWillDisappear()
>> 
>> In the NSCollectionView itself, I can see the items are removed from the 
>> ‘visibleItems()’ array, but the items themselves still seems to be known 
>> about by the collection view, as they will remain in the 
>> ‘selectionIndexPaths:’ if they were previously selected.
>> 
>> What’s really weird is that because we have multiple top level views, a lot 
>> of the code is reused on different displays, including the NSArrayController 
>> subclass that serves as the Delegate and DataSource for this 
>> NSCollectionView. It works perfectly fine in the other case. The main 
>> difference between these two top levels views, is that in the one that 
>> works, the Collection View is slaved to a Table View (ie the collection view 
>> shows the items in a relationship to the selection in the table view), where 
>> as in the one that doesn’t work, the behaviour is inverted (the selection in 
>> the collection view is the data source for a slaved table view). To be 
>> clear, though, both are displaying completely different Core Data entities. 
>> I don’t think I’ve missed anything, so as far as I can tell both 
>> NSCollectionViews are configured identically in the two XIBs.
>> 
>> The last weird thing is that the problem only seems to manifest if the 
>> application has previously been built. If I Make