Trying to make this work... (Xcode for mac NOT iPhone) - ArrayController - objective-c

I'm writing a stopwatch application for mac, and am currently working on the 'laps' feature. I am putting the laps into a Table View for better organization. I'm using an Array Controller to put things into the table.
Basically, what I'm trying to do is this:
[arrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:#"Lap 1",
#"lapNumber", nil]];
That works fine and dandy, but I'd like to be able to control that number next to lap using an integer representing the number of laps, called numLaps. Thus, my code would be:
[arrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:#"Lap %i",
numLaps, #"lapNumber", nil]];
However, as that is more than two commas before the nil, I think the program is getting screwed up. I am getting the following thrown in the console, though I don't exactly understand what it means / how to fix it:
2013-09-03 16:52:31.515 Popup[3242:303] +[NSMutableDictionary dictionaryWithObjectsAndKeys:]: second object of each pair must be non-nil. Or, did you forget to nil-terminate your parameter list?
2013-09-03 16:52:31.519 Popup[3242:303] (
0 CoreFoundation 0x00007fff9800a0a6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff9920b3f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff97fe8e31 +[NSDictionary dictionaryWithObjectsAndKeys:] + 433
3 Popup 0x00000001000035a0 -[PanelController btnLapWasClicked:] + 192
4 AppKit 0x00007fff96082a59 -[NSApplication sendAction:to:from:] + 342
5 AppKit 0x00007fff960828b7 -[NSControl sendAction:to:] + 85
6 AppKit 0x00007fff960827eb -[NSCell _sendActionFrom:] + 138
7 AppKit 0x00007fff96080cd3 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
8 AppKit 0x00007fff96080521 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
9 AppKit 0x00007fff9607fc9c -[NSControl mouseDown:] + 820
10 AppKit 0x00007fff9607760e -[NSWindow sendEvent:] + 6853
11 AppKit 0x00007fff96073744 -[NSApplication sendEvent:] + 5761
12 AppKit 0x00007fff95f892fa -[NSApplication run] + 636
13 AppKit 0x00007fff95f2dcb6 NSApplicationMain + 869
14 Popup 0x0000000100001652 main + 34
15 Popup 0x0000000100001624 start + 52
)
Any ideas how to implement what I'm trying to do in another fashion that won't confuse the program?
Thanks.

You should use the modern obj-c notation. That enables you to create dictionaries and arrays in a more natural way.
NSDictionary *dic = #{#"Laps ": #(numLaps), #"someotherkey":#"anditswalue"};
In the code you show the keys and values are not in pairs. You must always insert pairs. (For detailed reference see the NSDictionary documentation.)
NSString *key = #"laps";
NSString *value = [NSStringWithFormat:#"Lap %i", numLaps];
[arrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
value, key, nil]];
Also, you need to think over what you want to store in the dictionary. The keys and values are not apparent in your example.

Related

Why would iOS try to call rangeOfCharacterFromSet: on an NSIndexPath?

I'm getting the following error, which causes a SIGABRT:
2015-09-10 17:54:23.859 MyApp[1310:2027719] ERROR CRASH #(null) -[NSIndexPath rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0xc000000000000016
2015-09-10 17:54:23.879 MyApp[1310:2027719] ERROR Stack Trace: (
0 CoreFoundation 0x0000000183840248 <redacted> + 160
1 libobjc.A.dylib 0x00000001952640e4 objc_exception_throw + 60
2 CoreFoundation 0x00000001838472f4 <redacted> + 0
3 CoreFoundation 0x00000001838440a8 <redacted> + 928
4 CoreFoundation 0x000000018374696c _CF_forwarding_prep_0 + 92
5 UIKit 0x0000000188632a44 <redacted> + 104
6 UIKit 0x00000001887a0ff0 <redacted> + 76
7 UIKit 0x00000001887a10b0 <redacted> + 56
8 UIKit 0x00000001887a1194 <redacted> + 36
9 QuartzCore 0x0000000187bf0820 <redacted> + 320
10 QuartzCore 0x0000000187bf06c4 <redacted> + 32
11 QuartzCore 0x0000000187befe58 <redacted> + 276
12 QuartzCore 0x0000000187befbd8 <redacted> + 528
13 QuartzCore 0x0000000187be9300 <redacted> + 80
14 CoreFoundation 0x00000001837f7ff0 <redacted> + 32
15 CoreFoundation 0x00000001837f4f7c <redacted> + 360
16 CoreFoundation 0x00000001837f535c <redacted> + 836
17 CoreFoundation 0x0000000183720f74 CFRunLoopRunSpecific + 396
18 GraphicsServices 0x000000018d0436fc GSEventRunModal + 168
19 UIKit 0x0000000188322d94 UIApplicationMain + 1488
20 MyApp 0x00000001000437b0 main + 68
21 libdyld.dylib 0x000000019590ea08 <redacted> + 4
which looks like iOS is trying to send a message to an NSString selector, but the message was sent to an NSIndexPath. Weird!
I've since found the problem; I'd set the value of the text in a UILabel to be a pointer to an object in a CoreData object's NSNumber column (0xc000000000000016) instead of an NSString. My fix was added .intValue to the NSNumber before passing it to my enumToString: method.
typedef NS_ENUM(NSInteger, MyEnum)
{
MyEnum1 = 1,
MyEnum2,
MyEnum3
};
- (NSString*)enumToString:(MyEnum)enumValue
{
switch (enumValue) {
case MyEnum1:
return #"One";
case MyEnum2:
return #"Two";
case MyEnum3:
return #"Three";
}
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
// cdObject is a managed object in CoreData. Its enumValue column is an NSNumber.
cell.textLabel.text = [self enumToString:cdObject.enumValue];
return cell;
}
This just leaves the question: Why would this cause iOS to try to send a message to the non-existant selector -[NSIndexPath rangeOfCharacterFromSet:]?
The crash occurred just after completing a -[UITableViewDataSource tableView:cellForRowAtIndexPath:]
Ok, so the cause is most likely not some threading gone wrong. Core Data turns the NSManagedObjects into faults at some point. This might be related. Also, NSNumbers are kind of special objects: the pointer is a tagged pointer, and this tagged pointer might contain the actual numeric value. This might also be related. In any case, a message was sent to a pointer, and that pointer no longer points to an object that recognizes that message. Read here about tagged pointers: https://www.mikeash.com/pyblog/friday-qa-2012-07-27-lets-build-tagged-pointers.html

Getting error after execute NSMutableArray

Here is the code. I tried to create a object which includes the name, size and image(get from the resource) and then I add that object into NSMutableArray in order to show those object in NSTableView. However, after I run the code, I did get the correct counts of object in NSMutableArray and correct information in each object(name,size,image), but it still gives me error. Could you guys help me. I am a new Mac developer. Thanks !!
Here is the code:
#implementation AppDelegate{
NSMutableArray* _tableContents;
}
-(void)awakeFromNib{
NSString* imagePath = #"USB.png";
NSString* mountPath = #"/Volumes";
_tableContents = [[NSMutableArray alloc]init];
for(mountPath in [[NSWorkspace sharedWorkspace]mountedLocalVolumePaths])
{
if(0==[mountPath rangeOfString:#"/Volumes/"].location)
{
NSString* USBpath = [[[NSWorkspace sharedWorkspace]mountedLocalVolumePaths]objectAtIndex:count];
//get the name of USB drive
NSString* nameOfUSB = [USBpath substringFromIndex:9];
//get the size of USB drive
NSNumber *volumeSize;
NSURL *mountPathPicked = [NSURL fileURLWithPath:mountPath];
if([mountPathPicked getResourceValue:&volumeSize forKey:NSURLVolumeTotalCapacityKey error:nil])
{
NSDictionary *obj = #{#"name":nameOfUSB,
#"image":[NSImage imageNamed:imagePath],
#"size":volumeSize
};
//after I call the following line, it will give me error !!
[_tableContents addObject:obj];
}
}
count ++;
}
}
//I also use the following two methods in order to show the name, and image in NSTableView
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
return [_tableCountents count];
}
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSDictionary *flag = _tableContents[row];
NSString *identifier = [tableColumn identifier];//call different col we need identifier
if([identifier isEqualToString:#"MainCell"])
{
NSTableCellView *cellView = [tableView makeViewWithIdentifier:#"MainCell" owner:self];//give back specific cell named mainCell
[cellView.textField setStringValue:flag[#"name"]];
[cellView.imageView setImage:flag[#"image"]];
return cellView;
}
return nil;
}
There is no connection problems in GUI. And here is the error message:
2013-04-25 01:16:41.321 NAMEOFPROJECT[8243:303] An uncaught exception was raised
2013-04-25 01:16:41.322 NAMEOFPROJECT[8243:303] *** -[__NSArrayI objectAtIndex:]: index 7 beyond bounds [0 .. 3]
2013-04-25 01:16:41.329 NAMEOFPROJECT[8243:303] (
0 CoreFoundation 0x00007fff9147cb06 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff900c03f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff9142fb53 -[__NSArrayI objectAtIndex:] + 163
3 CDTOANYDRIVE 0x00000001000011d6 -[AppDelegate DetectingUSBDrives] + 710
4 CDTOANYDRIVE 0x0000000100000efb -[AppDelegate awakeFromNib] + 43
5 AppKit 0x00007fff899631a8 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1234
6 AppKit 0x00007fff89b79976 -[NSNib _instantiateNibWithExternalNameTable:] + 610
7 AppKit 0x00007fff89b7a41a -[NSNib instantiateNibWithExternalNameTable:] + 17
8 AppKit 0x00007fff89b262b4 -[NSTableRowData _unarchiveViewWithIdentifier:owner:] + 520
9 CDTOANYDRIVE 0x000000010000174b -[AppDelegate tableView:viewForTableColumn:row:] + 219
10 AppKit 0x00007fff89b279a2 -[NSTableRowData _addViewToRowView:atColumn:row:] + 324
11 AppKit 0x00007fff89b2766f -[NSTableRowData _addViewsToRowView:atRow:] + 151
12 AppKit 0x00007fff89b25c05 -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 415
13 AppKit 0x00007fff89b2598a -[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] + 272
14 AppKit 0x00007fff89b24c59 -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 740
15 AppKit 0x00007fff89b247f1 -[NSTableRowData updateVisibleRowViews] + 119
16 AppKit 0x00007fff89afc5d7 -[NSTableView layout] + 165
17 AppKit 0x00007fff89aafe95 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 112
18 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
19 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
20 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
21 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
22 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
23 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
24 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
25 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
26 AppKit 0x00007fff89aafd2e -[NSView layoutSubtreeIfNeeded] + 615
27 AppKit 0x00007fff89aab4dc -[NSWindow(NSConstraintBasedLayout) layoutIfNeeded] + 201
28 AppKit 0x00007fff899d96a8 -[NSView _layoutAtWindowLevelIfNeeded] + 99
29 AppKit 0x00007fff899d8fe6 -[NSView _sendViewWillDrawInRect:clipRootView:] + 87
30 AppKit 0x00007fff899a59b1 -[NSView displayIfNeeded] + 1044
31 AppKit 0x00007fff89a62a48 -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 1377
32 AppKit 0x00007fff89a62068 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 940
33 AppKit 0x00007fff89a61c4f -[NSWindow orderWindow:relativeTo:] + 159
34 AppKit 0x00007fff89963266 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1424
35 AppKit 0x00007fff8994214d loadNib + 317
36 AppKit 0x00007fff89941679 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 219
37 AppKit 0x00007fff899414ae -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] + 200
38 AppKit 0x00007fff8994128e +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 360
39 AppKit 0x00007fff8993da2f NSApplicationMain + 398
40 CDTOANYDRIVE 0x0000000100000e82 main + 34
41 libdyld.dylib 0x00007fff9385a7e1 start + 0
42 ??? 0x0000000000000003 0x0 + 3
)
And the above error shows twice !!
I have tried your code in a mini-app and It works fine. There are few things that I might highlight:
Your exception occurs in the method DetectingUSBDrives, for which we don't have any code. I'm assuming that you have pasted the code in the awakeFromNib method.
You are using count as an index. Is this varibale initialized at zero?
The fact that the error appears twice suggests that your cell views hold a reference to your app delegate, which means that awakeFromNib is called once for each view creation. This can create many problem since you are initializing _tableOfContents there. You might want to move all that code to the init method instead.

Suggestions in popover for NSTokenField

I'm trying to subclass NSTokenField to show a popover with token suggestions.
I set my subclass as the super delegate, I intercept the – tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem: delegate method and return nil to prevent the menu from showing. It works fine except by returning nil the token field doesn't complete the string entered by the user.
Currently I'm using the following lines in – tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem: to add the suggested string:
NSText *editingText = [[self window] fieldEditor:NO forObject:self];
NSString *suggestionString = [filteredStrings objectAtIndex:0];
NSString *missingPart = [(NSString *)suggestionString substringFromIndex:[substring length]];
NSUInteger insertionPoint = [editingText selectedRange].location;
NSMutableString *currentStringPlusSuggestionString = [[editingText string] mutableCopy];
[currentStringPlusSuggestionString insertString:missingPart atIndex:insertionPoint];
[editingText setString:[stringWithSuggestionString copy]];
Unfortunately it generates an error when I try to insert text between 2 tokens. Here is the error but I don't really understand why the string is out of bounds.
[NSBigMutableString _getBlockStart:end:contentsEnd:forRange:stopAtLineSeparators:]: Range or index out of bounds'
0 CoreFoundation 0x00007fff88835716 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8adae470 objc_exception_throw + 43
2 CoreFoundation 0x00007fff888354ec +[NSException raise:format:] + 204
3 Foundation 0x00007fff8efd6627 -[NSString _getBlockStart:end:contentsEnd:forRange:stopAtLineSeparators:] + 157
4 AppKit 0x00007fff8bd37c6f _NSFastFillAllLayoutHolesForGlyphRange + 285
5 AppKit 0x00007fff8bd008fa -[NSLayoutManager textContainerForGlyphAtIndex:effectiveRange:] + 238
6 AppKit 0x00007fff8bb4a18f -[NSTextView(NSSharing) didChangeText] + 194
7 AppKit 0x00007fff8bbe00ee -[NSTokenFieldCell textView:willChangeSelectionFromCharacterRange:toCharacterRange:] + 776
8 AppKit 0x00007fff8bd32795 -[NSControl textView:willChangeSelectionFromCharacterRange:toCharacterRange:] + 112
9 AppKit 0x00007fff8bd30724 -[NSTextView(NSSharing) setSelectedRanges:affinity:stillSelecting:] + 1076
10 AppKit 0x00007fff8bcf8438 -[NSLayoutManager textStorage:edited:range:changeInLength:invalidatedRange:] + 406
11 AppKit 0x00007fff8bcf828a -[NSTextStorage _notifyEdited:range:changeInLength:invalidatedRange:] + 154
12 AppKit 0x00007fff8bda0f75 -[NSTextStorage processEditing] + 202
13 AppKit 0x00007fff8bc02c54 -[NSTextStorage endEditing] + 79
14 PopoverTokenField 0x0000000100002f55 -[JSTokenField tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:] + 1013
Alternatively, does anyone know another way to let the token field complete the string without having the menu?

NSTask in Objective-C

So I'm trying to run some terminal commands from my program, and I am getting some confusing errors.
Im a newer developer coming from Java, so I may be missing something.
Heres the code:
NSTask *task = [[NSTask alloc] init];
NSString *commitText = [commitMessage stringValue];
NSString *a = [NSString stringWithFormat:#"cd %#", dirPath];
NSString *c = [NSString stringWithFormat:#"git commit -m '%#'", commitText];
NSArray *commands = [[NSArray alloc]initWithObjects:a,
#"git add 'Project'",
c,
#"git push origin HEAD",
nil];
[task setLaunchPath:#"/bin/sh"];
// Do commands
NSArray *args = [NSArray arrayWithObjects:commands,
nil];
[task setArguments: args];
[task launch];
And here are the errors:
2012-06-09 08:35:20.561 Auto Git[5433:403] -[__NSArrayI fileSystemRepresentation]: unrecognized selector sent to instance 0x7fb250d6a1e0
2012-06-09 08:35:20.561 Auto Git[5433:403] -[__NSArrayI fileSystemRepresentation]: unrecognized selector sent to instance 0x7fb250d6a1e0
2012-06-09 08:35:20.679 Auto Git[5433:403] (
0 CoreFoundation 0x00007fff870b4f56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90e35d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff871411be -[NSObject doesNotRecognizeSelector:] + 190
3 CoreFoundation 0x00007fff870a1e23 ___forwarding___ + 371
4 CoreFoundation 0x00007fff870a1c38 _CF_forwarding_prep_0 + 232
5 Foundation 0x00007fff9174f3a3 -[NSConcreteTask launchWithDictionary:] + 901
6 Auto Git 0x000000010d83c6db -[Push push:] + 571
7 CoreFoundation 0x00007fff870a470d -[NSObject performSelector:withObject:] + 61
8 AppKit 0x00007fff8e0f8f7e -[NSApplication sendAction:to:from:] + 139
9 AppKit 0x00007fff8e0f8eb2 -[NSControl sendAction:to:] + 88
10 AppKit 0x00007fff8e0f8ddd -[NSCell _sendActionFrom:] + 137
11 AppKit 0x00007fff8e0f82a0 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014
12 AppKit 0x00007fff8e177fc4 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489
13 AppKit 0x00007fff8e0f6eaa -[NSControl mouseDown:] + 786
14 AppKit 0x00007fff8e0c2348 -[NSWindow sendEvent:] + 6306
15 AppKit 0x00007fff8e05ba55 -[NSApplication sendEvent:] + 5593
16 AppKit 0x00007fff8dff20c6 -[NSApplication run] + 555
17 AppKit 0x00007fff8e26e244 NSApplicationMain + 867
18 Auto Git 0x000000010d83bff2 main + 34
19 Auto Git 0x000000010d83bfc4 start + 52
20 ??? 0x0000000000000003 0x0 + 3
)
Thanks!
Your arguments array contains an array. It should be an array of strings. Use your commands object as that parameter for NSTask.
I think the problem is that your passing a array with a array of strings to setArguments. You should pass an array with strings only not an nested array.
But I think you misunderstand how the arguments to NSTask works. You should probably do something like this:
[task setArguments:[[[NSArray alloc] initWithObjects:
#"git", #"add", #"Project", nil]
autorelease]];
Etc, or if you really want to use sh you probably need to add some ; to separate the shell commands.

Get iTunes Artwork for Current Song with ScriptingBridge

I have been trying to figure out how to get the iTunes artwork for the currently playing song with scripting bridge. I have gotten to a point where it works for some songs, but for others, I get a SIGABRT. I'm not sure what the issue could be, so any help would be greatly appreciated. Here is what I have so far:
iTunesApplication * iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
NSImage *songArtwork;
iTunesTrack *current = [iTunes currentTrack];
iTunesArtwork *artwork = (iTunesArtwork *)[[[current artworks] get] lastObject];
if(artwork != nil)
songArtwork = [artwork data];
else
songArtwork = [NSImage imageNamed:#"Image.tiff"];
NSMenuItem *artworkMenuItem = [[NSMenuItem alloc] initWithTitle:#"" action:NULL keyEquivalent:#""];
[songArtwork setSize:NSMakeSize(128, 128)];
[artworkMenuItem setImage:songArtwork];
[Menu insertItem:artworkMenuItem atIndex:0];
I for some songs it works, and displays the artwork nicely in the menu item, but for others I get a SIGABRT on the line:
[songArtwork setSize:NSMakeSize(128, 128)];
The output of the console is as follows:
2011-08-12 23:13:20.094 SongViewer[2146:707] -[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70
2011-08-12 23:13:20.095 SongViewer[2146:707] An uncaught exception was raised
2011-08-12 23:13:20.096 SongViewer[2146:707] -[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70
2011-08-12 23:13:20.097 SongViewer[2146:707] (
0 CoreFoundation 0x00007fff86f11986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8b04cd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff86f9d5ae -[NSObject doesNotRecognizeSelector:] + 190
3 CoreFoundation 0x00007fff86efe803 ___forwarding___ + 371
4 CoreFoundation 0x00007fff86efe618 _CF_forwarding_prep_0 + 232
5 SongViewer 0x0000000100002a83 -[IPMenulet awakeFromNib] + 4483
6 CoreFoundation 0x00007fff86f089e1 -[NSObject performSelector:] + 49
7 CoreFoundation 0x00007fff86f08962 -[NSSet makeObjectsPerformSelector:] + 274
8 AppKit 0x00007fff8d9d9c27 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1245
9 AppKit 0x00007fff8d9d01b9 loadNib + 322
10 AppKit 0x00007fff8d9cf6b6 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
11 AppKit 0x00007fff8d9cf5d1 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
12 AppKit 0x00007fff8d9cf514 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
13 AppKit 0x00007fff8dc42355 NSApplicationMain + 398
14 SongViewer 0x0000000100001882 main + 34
15 SongViewer 0x0000000100001854 start + 52
)
2011-08-12 23:13:20.098 SongViewer[2146:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff86f11986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8b04cd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff86f9d5ae -[NSObject doesNotRecognizeSelector:] + 190
3 CoreFoundation 0x00007fff86efe803 ___forwarding___ + 371
4 CoreFoundation 0x00007fff86efe618 _CF_forwarding_prep_0 + 232
5 SongViewer 0x0000000100002a83 -[IPMenulet awakeFromNib] + 4483
6 CoreFoundation 0x00007fff86f089e1 -[NSObject performSelector:] + 49
7 CoreFoundation 0x00007fff86f08962 -[NSSet makeObjectsPerformSelector:] + 274
8 AppKit 0x00007fff8d9d9c27 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1245
9 AppKit 0x00007fff8d9d01b9 loadNib + 322
10 AppKit 0x00007fff8d9cf6b6 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
11 AppKit 0x00007fff8d9cf5d1 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
12 AppKit 0x00007fff8d9cf514 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
13 AppKit 0x00007fff8dc42355 NSApplicationMain + 398
14 SongViewer 0x0000000100001882 main + 34
15 SongViewer 0x0000000100001854 start + 52
)
terminate called throwing an exception(gdb)
If anyone has any idea what could be wrong, please let me know!!
Ok so I figured it out. The solution is to use the NSData raw data provided by the API rather than the NSImage. So I used:
NSImage *songArtwork = [[NSImage alloc] initWithData:[artwork rawData]];
rather than
songArtwork = [artwork data];
I have to fetch batch of track artworks from iTunes and use ‘rawData’ too.
But this way is inefficient.
I found a better way (actually it decreases ‘fetch’ time about 2 times, it’s very significant when fetching artworks for many tracks using ‘valueForKey:’ according to «Improving the Performance of Scripting Bridge Code»).
So I decided to understand what’s wrong with iTunesArtwork ‘data’ property.
We expect to get an NSImage object (according to iTunes.h ), but real object is kind of ‘NSAppleEventDescriptor’. And it’s easy to guess, that this object contains an image for us. So we can just use ‘data’ property to get image data. And this is really faster than getting ‘rawData’ from iTunesArtwork.
But sometimes iTunes return NSImage object instead NSAppleEventDescriptor. This is an strange behavior, but it's still faster then using rawData.