tableView crashes on end up with more than 16 items - ios

This is very confusing.
I have a UITableView, which updates and works fine until it gets more than 16 items then it crashes when trying to endUpdates after calling insertRowsAtIndexPaths.
The NSIndexPaths being added are all valid. -numberOfRowsInSection returns the correct number. It is not throwing an error related to the data set, rather it crashes with
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
when endUpdates is called on the tableView.
The data source is all there, the NSIndexPaths are fine. the code works fine between 0 and 16 rows, but when I add a 17th it crashes. Additionally if I start it with 22 items it works fine, when I add the 23rd it crashes... if I call reload data instead of doing the update and insert process it works fine, so it's nothing to do with the data itself, and it shouldn't be anything to do with how I'm inserting the rows since it works through 16...
I'm completely perplexed. Here is my update method. It is being called on the main thread at all times.
- (void)updateConversation:(NSNotification*)notification
{
NSDictionary *updateInfo = [notification userInfo];
//NSLog(#"Got update %#", updateInfo);
if ([[updateInfo objectForKey:#"success"] integerValue] == YES) {
[self updateConversationUI];
int addedStatementCount = [[updateInfo objectForKey:#"addedStatementCount"] intValue];
if (addedStatementCount > 0) {
//[self.tableView reloadData];
[self.tableView beginUpdates];
int previousStatmentCount = [[updateInfo objectForKey:#"previousStatmentCount"] intValue];
NSLog(#"owner %i, Was %i, now %i, change of %i", self.owner, previousStatmentCount, (int)self.conversation.statements.count, addedStatementCount);
NSMutableArray *rowPaths = [[NSMutableArray alloc] init];
for (int i = previousStatmentCount; i < previousStatmentCount + addedStatementCount; i++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
[rowPaths addObject:path];
}
[self.tableView insertRowsAtIndexPaths:rowPaths withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[rowPaths lastObject] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
}
The rest of the crash past [self.tableView endUpdates] is UITableView
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x000000010189b795 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001015fe991 objc_exception_throw + 43
2 CoreFoundation 0x0000000101852564 -[__NSArrayM insertObject:atIndex:] + 820
3 UIKit 0x0000000100317900 __46-[UITableView _updateWithItems:updateSupport:]_block_invoke691 + 173
4 UIKit 0x00000001002b5daf +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 460
5 UIKit 0x00000001002b6004 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 57
6 UIKit 0x00000001003174cb -[UITableView _updateWithItems:updateSupport:] + 2632
7 UIKit 0x0000000100312b18 -[UITableView _endCellAnimationsWithContext:] + 11615
8 Dev App 0x0000000100006036 -[ConversationViewController updateConversation:] + 998
9 CoreFoundation 0x00000001018f121c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
10 CoreFoundation 0x000000010185370d _CFXNotificationPost + 2381
11 Dev App 0x00000001000055ac -[ConversationManager postNotification:] + 92
12 Foundation 0x0000000101204557 __NSThreadPerformPerform + 227
13 CoreFoundation 0x000000010182aec1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
14 CoreFoundation 0x000000010182a792 __CFRunLoopDoSources0 + 242
15 CoreFoundation 0x000000010184661f __CFRunLoopRun + 767
16 CoreFoundation 0x0000000101845f33 CFRunLoopRunSpecific + 467
17 GraphicsServices 0x00000001039a23a0 GSEventRunModal + 161
18 UIKit 0x0000000100261043 UIApplicationMain + 1010
19 Dev App 0x0000000100003613 main + 115
20 libdyld.dylib 0x0000000101f2a5fd start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
This seems like a bug in the OS, the stack would indicate that it's something to do with the animation block but it happens no matter what I set the animation to, including none.
And to re-state. This works through 16 items, then inserting items past that causes a crash. It is also called at initial setup to load data, and it will load any number of items there, including well over 16. But when called again, purely as an update from 16 or more to something higher it will crash.
Most bizarre issue I've yet to encounter with table views...
under iOS 7 on device and simulator, latest Xcode for reference.

It seems that the problem is caused by my call of scrollToRowAtIndexPath (even though it crashes before it gets there...) combined with implementing tableView:estimatedHeightForRowAtIndexPath: by removing the row height estimate the crash went away... still seems like a bug in the animation system for tables to me. Thankfully I don't need the estimated row height, I had forgotten I had implemented it (trying to play nice by iOS 7 bites me again).

Place strategic breakpoints when you are incrementing the statement count, go through the loop of adding the rows as many times as you need to, and locate the statement that it's causing the crash, at that moment take a look at your objects and look for nil values as the error you are having it's trying to insert a nil object(or un-existent) from an Array.
I would personally recommend you to go through this loop entirely while keeping an exe for the path and previous statement count .
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];

in my case the tableView:heightForHeaderInSection: method has been missing,
hadn't implemented the tableView:estimatedHeightForRowAtIndexPath method so this also could be solving the problem if you aren't using tableView:estimatedHeightForRowAtIndexPath:

Your problem is that you don't update the dataSource the tableView is using.
if you insert a row, you need to insert the appropriate object to the array the tableView is using.
Goodluck!

Related

NSTableView binding + delegate causes array index error

I have a view-based NSTableView which uses bindings to an NSArrayController.
As soon as I add a delegate to the table view, I start getting:
Ignoring exception raised in void run_cocoa_block(void *): *** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
and
MyApp[59144:25384659] *** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
MyApp[59144:25384659] (
0 CoreFoundation 0x00007fff93410452 __exceptionPreprocess + 178
1 libobjc.A.dylib 0x00007fff9601af7e objc_exception_throw + 48
2 CoreFoundation 0x00007fff93327775 -[__NSArrayM objectAtIndex:] + 245
3 AppKit 0x00007fff9bd7ad31 -[NSTableRowData _addViewToRowView:atColumn:row:] + 535
4 AppKit 0x00007fff9bd7a98e -[NSTableRowData _addViewsToRowView:atRow:] + 184
5 AppKit 0x00007fff9bd791a7 -[NSTableRowData _initializeRowView:atRow:] + 390
6 AppKit 0x00007fff9bd77907 -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 416
If I remove the delegate connection, everything works fine... the table fills properly from the NSArrayController that it is bound to, and the cells/columns get the correct data as well.
I need the delegate to use
-(BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor
What might be causing this?
Elsewhere in the app, I have a sheet that also uses a view-based NSTableView with bindings and it works fine with a delegate.
In awakeFromNib:, I was calling:
[[self itemsController] setContent:[[[NSMutableArray alloc] init] autorelease]];
this worked in a cell-based NSTableView but not in a view-based one. I'm not sure why, but giving it this empty array may have been happening after the binding took place but before the OS did something else with it and the empty array was confusing it.

GMSPolygon array iOS crash

I Have an extremely strange issue with the GMSPolygon object.
Just out of nowhere my code crashes with the error "Unrecognized selector send to instance 0x...."
(Yes it worked all day, and suddenly it starts crashing)
I am using an array of Polygons (to keep track of them and update them dynamically) and I initialize them as follows in my -viewDidLoad:
GMSPolygon *myPoly[50];
--
GMSMutablePath *path = [[GMSMutablePath alloc] init];
// set some fake coordinates, initializing a Polygon with an empty path seems to crash as well...
[path addCoordinate:CLLocationCoordinate2DMake(1,0)];
[path addCoordinate:CLLocationCoordinate2DMake(-1,0)];
[path addCoordinate:CLLocationCoordinate2DMake(0,1)];
for (int i=0;i<50;i++) {
myPoly[i] = [GMSPolygon polygonWithPath:path];
myPoly[i].map = nil;
}
Later on in my program I try to acces the object again in the same way, first set it to nil so it will be removed from the map, and then update and if necessary display it again
for (int i=0;i<50;i++) {
myPoly[i] = [GMSPolygon polygonWithPath:path];
myPoly[i].map = nil; <--------- CRASH
// Do other stuf here, update the Polygon data and if needed
// display again as follows:
myPoly[i].map = mapView_;
}
But it seems to crash..
Same thing happens if I put the GMSPolygon in an NSMutable array. Initializing the array is fine, but getting the GMSPolygon out of the array and setting the .map property gives the same crash..
UPDATE:
It seems be caused by the object Memory locations.. If it works fine, memory locations are as follows:
[0] GMSPolygon * 0x1558ed750 0x00000001558ed750 <--- viewDidLoad for-loop
[0] GMSPolygon * 0x1558ed750 0x00000001558ed750 <--- other function for-loop
When it crashes
[0] GMSPolygon * 0x12e7cbf30 0x000000012e7cbf30 <--- viewDidLoad for-loop
[0] GMSPolygon * 0x129d36630 0x0000000129d36630 <--- other function for-loop
The object is only initialized once in the viewDidLoad, nowhere else!
It obviously explains the crash if the objects memory location are different.. but what's happening here?
Any one an idea why?
UPDATE 2, Got Crash log now:
2016-04-14 15:16:49.618 myApp[1130:240689] -[GMSMutablePath setMap:]: unrecognized selector sent to instance 0x1540bb560
2016-04-14 15:16:49.627 myApp[1130:240689] void uncaughtExceptionHandler(NSException *__strong) [Line 354] CRASH: -[GMSMutablePath setMap:]: unrecognized selector sent to instance 0x1540bb560
2016-04-14 15:16:49.688 myApp[1130:240689] void uncaughtExceptionHandler(NSException *__strong) [Line 355] Stack Trace: (
0 CoreFoundation 0x0000000182ebee50 <redacted> + 148
1 libobjc.A.dylib 0x0000000182523f80 objc_exception_throw + 56
2 CoreFoundation 0x0000000182ec5ccc <redacted> + 0
3 CoreFoundation 0x0000000182ec2c74 <redacted> + 872
4 CoreFoundation 0x0000000182dc0d1c _CF_forwarding_prep_0 + 92
5 myApp 0x00000001001115a0 -[mapViewController plotPoly] + 2028
6 myApp 0x000000010012c944 -[mapViewController mapView:didChangeCameraPosition:] + 556
7 CoreFoundation 0x0000000182ec4ae0 <redacted> + 144
8 CoreFoundation 0x0000000182dbc548 <redacted> + 284
9 CoreFoundation 0x0000000182dc0e70 <redacted> + 60
10 myApp 0x0000000100203370 -[GMSDelegateForward forwardInvocation:] + 108
11 CoreFoundation 0x0000000182ec2aa4 <redacted> + 408
12 CoreFoundation 0x0000000182dc0d1c _CF_forwarding_prep_0 + 92
13 myApp 0x0000000100188fec -[GMSMapView updateWithCamera:] + 176
14 Foundation 0x0000000183893ffc <redacted> + 340
15 CoreFoundation 0x0000000182e75124 <redacted> + 24
16 CoreFoundation 0x0000000182e74bb8 <redacted> + 540
17 CoreFoundation 0x0000000182e728b8 <redacted> + 724
18 CoreFoundation 0x0000000182d9cd10 CFRunLoopRunSpecific + 384
19 GraphicsServices 0x0000000184684088 GSEventRunModal + 180
20 UIKit 0x0000000188069f70 UIApplicationMain + 204
21 myApp 0x000000010013dd3c main + 124
22 libdyld.dylib 0x000000018293a8b8 <redacted> + 4)
2016-04-14 15:16:49.700 myApp[1130:240689] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GMSMutablePath setMap:]: unrecognized selector sent to instance 0x1540bb560'
*** First throw call stack:
(0x182ebee38 0x182523f80 0x182ec5ccc 0x182ec2c74 0x182dc0d1c 0x1001115a0
0x10012c944 0x182ec4ae0 0x182dbc548 0x182dc0e70 0x100203370 0x182ec2aa4
0x182dc0d1c 0x100188fec 0x183893ffc 0x182e75124 0x182e74bb8 0x182e728b8
0x182d9cd10 0x184684088 0x188069f70 0x10013dd3c 0x18293a8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
I am stunned now.
The initial initialization works fine, the Polygons are drawn as the should, but as soon as I call the function to redraw the polygons, the crash happens.. and strange enough now I see why it crashes, but I don't understand.. It changes the first 5 array entry's to GMSMutablePath and GMSPolyLine , instead of GMSPolygon ?!, see link to picture below.. And have no idea why, because I am 100% sure the array of GMSPolygon is not touched anywhere else in the mean time..
Picture of of change in Array type
I can't post a comment yet due to my reputation. Just like what Dan said, use NSArray or NSMutableArray to store your objects. Then do your stuff.
UPDATE:
Here are my suggestions:
Add All Exceptions to your breakpoint navigator.
Try testing your code without loop.
Try adding float values as your coordinates.
See example code below:
GMSMutablePath *prettyPoly = [GMSMutablePath path];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(52.506191, 1.83197)];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(52.05249, 1.650696)];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(51.92225, 1.321106)];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(51.996719, 1.219482)];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(52.049112, 1.244202)];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(52.197507, 1.334839)];
[prettyPoly addCoordinate:CLLocationCoordinate2DMake(52.519564, 1.801758)];
GMSPolygon *polygon = [GMSPolygon polygonWithPath: prettyPoly];
polygon.fillColor = [UIColor colorWithRed:0 green:0.25 blue:0 alpha:0.3];
polygon.strokeColor = [UIColor greenColor];
polygon.strokeWidth = 5;
polygon.map = self.googleMap;
If everything failed:
- Refer to this doc: https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_polygon#properties
How about you try Polyline class and see this example: https://developers.google.com/maps/documentation/ios-sdk/shapes#add_a_polyline
Last, try seeking help from Google Forum, or from the repo of that library you are using.

NSGenericException reason Collection <NSConcreteMapTable: xxx>

this is the error that i see when present SKScene, this error occurs randomly and are not able to replicate
* Terminating app due to uncaught exception 'NSGenericException', reason: '* Collection < NSConcreteMapTable: 0x1459da60 > was mutated while being enumerated.'
what's happen?
tell me if you need any other info
thanks
EDIT:
*** First throw call stack:
(
0 CoreFoundation 0x025601e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x022298e5 objc_exception_throw + 44
2 CoreFoundation 0x025efcf5 __NSFastEnumerationMutationHandler + 165
3 Foundation 0x01e47f03 -[NSConcreteMapTable countByEnumeratingWithState:objects:count:] + 66
4 CoreFoundation 0x0253d77f -[__NSFastEnumerationEnumerator nextObject] + 143
5 SpriteKit 0x01d009f2 +[SKTextureAtlas(Internal) findTextureNamed:] + 232
6 SpriteKit 0x01cf709c __26-[SKTexture loadImageData]_block_invoke + 1982
7 SpriteKit 0x01d34d09 _Z14SKSpinLockSyncPiU13block_pointerFvvE + 40
8 SpriteKit 0x01cf6898 -[SKTexture loadImageData] + 228
9 SpriteKit 0x01cf65d9 __51+[SKTexture preloadTextures:withCompletionHandler:]_block_invoke + 241
10 libdispatch.dylib 0x02b117b8 _dispatch_call_block_and_release + 15
11 libdispatch.dylib 0x02b264d0 _dispatch_client_callout + 14
12 libdispatch.dylib 0x02b14eb7 _dispatch_root_queue_drain + 291
13 libdispatch.dylib 0x02b15127 _dispatch_worker_thread2 + 39
14 libsystem_c.dylib 0x02de1e72 _pthread_wqthread + 441
15 libsystem_c.dylib 0x02dc9daa start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I get the same exception on occasion. It's been around for a while and I've been trying to pinpoint it for weeks.
My suspicion is that it may occur due to preloading textures, either manually or triggered automatically by Sprite Kit while at the same time some other code causes textures to be loaded or accessed.
I have reduced my preloadTextures: calls to a single one but I still get the issue, just less often. I have tried to performSelector:onMainThread: whenever I run a selector that accesses or loads images (or just might internally) from within a completionBlock or other code that runs on a different thread.
I haven't had this crash the entire day today after I moved my user interface code to the main thread (it was called from a completion handler). I can't say 100% for sure whether this fixed it though.
I hope this helps a little. There's definitely something finicky going on, and if you do po 0x1459da60 (in lldb's command window, using the address provided by the exception) you'll see that it is the SKTextureAtlas texture list that is being modified. I hope that helps you pinpoint where the issue is coming from on your side.
From what I can tell this a sprite kit bug in the sprite kit method:
preloadTextures: withCompletionHandler:
The only way I was able to fix this was by removing this method completely.
According to apple docs the textures also get loaded if you access the size property.
So my workaround is just to do exactly that:
for (SKTexture *texture in self.texturesArray) {
texture.size;
}
It's not pretty but it works!
I had the same problem, when I tried to preload two simple animations. I tried to preload the animations in a dictionary and have them ready to be called via a string key. Here is what I tried
-(void)setupAnimDict {
animDict = [[NSMutableDictionary alloc] init];
[animDict setObject:[self animForName:#"blaze" frames:4] forKey:#"blaze"];
[animDict setObject:[self animForName:#"flame" frames:4] forKey:#"flame"];
}
-(SKAction *)animForName:(NSString *)name frames:(int)frames {
NSArray *animationFrames = [self setupAnimationFrames:name base:name num:frames];
SKAction *animationAction = [SKAction animateWithTextures:animationFrames timePerFrame:0.10 resize:YES restore:NO];
return [SKAction repeatActionForever:animationAction];
}
-(NSArray *)setupAnimationFrames:(NSString *)atlasName base:(NSString *)baseFileName num:(int)numberOfFrames {
[self preload:baseFileName num:numberOfFrames];
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:numberOfFrames];
SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:atlasName];
for (int i = 0; i < numberOfFrames; i++) {
NSString *fileName = [NSString stringWithFormat:#"%#%01d.png", baseFileName, i];
[frames addObject:[atlas textureNamed:fileName]];
}
return frames;
}
-(void)preload:(NSString *)baseFileName num:(int)numberOfFrames {
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:numberOfFrames];
for (int i = 0; i < numberOfFrames; i++) {
NSString *fileName = [NSString stringWithFormat:#"%#%01d.png", baseFileName, i];
[frames addObject:[SKTexture textureWithImageNamed:fileName]];
}
[SKTexture preloadTextures:frames withCompletionHandler:^(void){}];
}
When I called the setupDict method I sometimes got the same error as you. The problem was that preloading of my two animations run into each other. I got rid of the error by changing the
[SKTexture preloadTextures:frames withCompletionHandler:^(void){}];
to
if ([baseFileName isEqualToString:#"blaze"]) {
[SKTexture preloadTextures:frames withCompletionHandler:^{
[self setupFlame];
}];
} else {
[SKTexture preloadTextures:frames withCompletionHandler:^(void){}];
}
so that the first preloading was done before I attempted to preload the other.
I don't know if this is your problem, but if it is let us know.
Same thing still happening for me in Xcode 6.3 beta / Swift 1.2. Here is a temporary fix that has worked for me.
SKTextureAtlas.preloadTextureAtlases([SKTextureAtlas(named: "testAtlas")], withCompletionHandler: {
dispatch_async(dispatch_get_main_queue(), {
handler()
})
})
I actually wrapped this in a function so that all preloads route through it. That way if it gets fixed on the SpriteKit side, or if there are major flaws with this approach, I can remove the dispatch.

NSMutableData appendBytes is setting length to -1 and crashing

I'm getting a rare and intermittent crash which looks like appendBytes being called with -1 as it's length.
now, I've hard coded the "length" argument every time I've used this method so I can't see how this could happen and worse still I can't see how I could test for and avoid this crash.
here's the top of the stack and the exception (note the ~4.2b length):
*** Terminating app due to uncaught exception 'NSMallocException', reason: '*** -[NSConcreteMutableData appendBytes:length:]: unable to allocate memory for length (4294967295)'
*** Call stack at first throw:
(
0 CoreFoundation 0x91ec5a67 __raiseError + 231
1 libobjc.A.dylib 0x9950a149 objc_exception_throw + 155
2 CoreFoundation 0x91e2d289 +[NSException raise:format:arguments:] + 137
3 CoreFoundation 0x91e2d1f9 +[NSException raise:format:] + 57
4 Foundation 0x92d2489e _NSMutableDataGrowBytes + 1136
5 Foundation 0x92d24391 -[NSConcreteMutableData appendBytes:length:] + 354
here's a simplified version of the code that's supposedly crashing:
if (self.isConnectedToService) {
NSMutableData *myData = [NSMutableData data];
float newValue = PanValue;
const char theTwo[] = {(char)Chan_L, (char)PanParam};
[myData appendBytes:&theTwo length:2];
[myData appendBytes:&newValue length:4];
}
So length is always 2 or 4.
I've tested different situations in which the buffers contain more or less than 2 and 4 and I've never managed to cause this crash intentionally.
I've got the same code running on both MacOS10.7.4 and iOS6.0(on iPad3) and see this issue occasionally on both platforms.
so how is appendBytes getting that bogus value?

NSArray exception when adding track to starred playlist

Sometimes, I'm getting a fatal exception when trying to "star" a track in cocoalibspotify. I'm logging in with a user with a heavy dataset (hundreds of playlists, but < 15 starred tracks).
This is how I "star" the SPTrack:
[[[[SPSession sharedSession] starredPlaylist] items] addObject:myTrack];
... and the stack trace:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectsAtIndexes:]: index 12 beyond bounds [0 .. 11]'
*** Call stack at first throw:
(
0 CoreFoundation 0x01e125a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x021a1313 objc_exception_throw + 44
2 CoreFoundation 0x01da0f99 -[NSArray objectsAtIndexes:] + 633
3 Foundation 0x016a250b -[NSKeyValueArray objectsAtIndexes:] + 110
4 Foundation 0x016aaca6 NSKeyValueDidChangeByArrayMutation + 103
5 Foundation 0x01610c30 NSKeyValueDidChange + 266
6 Foundation 0x016aba95 -[NSObject(NSKeyValueObserverNotification) didChange:valuesAtIndexes:forKey:] + 123
7 Foundation 0x016a4d0e -[NSKeyValueNotifyingMutableArray addObject:] + 239
8 MyApp 0x000922cd -[PlaylistManager starTrack:] + 285
...
This only seems to happen within a minute or two after logging in (i.e. user data is loaded), so I'm guessing it might be an issue where the data isn't fully loaded or something?
I've tried to find out if there's any properties to observe in order to find out when everything's fully loaded. But as the array might be empty (and the user might not have starred any tracks before), it seems like there's no good way of validating that everything's loaded...? The loaded property of SPPlaylist seems to refer to the playlist metadata, and not its tracks (?).
Any ideas?
You are getting the So it looks like you're not supposed to manipulate that array directly. Instead call [myTrack setStarred:YES];
Basically, I just went through the entire Spotify API for you to find that answer.
A full code sample for this:
-(void)starTrack:(NSString *)uri {
NSURL *trackURL = [NSURL URLWithString:uri];
[[SPSession sharedSession] trackForURL:trackURL callback:^(SPTrack *track) {
if (track != nil) {
[SPAsyncLoading waitUntilLoaded:track timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *tracks, NSArray *notLoadedTracks) {
[track setStarred:YES];
}];
}
}];
}

Resources