I have this code below. The thing is, each time I click on the "SPIN" ccmenuitem, the program crashes with a "Program received signal: SIGABRT"
Here's the output in the console:
2011-07-29 13:52:52.906 HelloWorld[1031:207] -[NSCFString shuffle]: unrecognized selector sent to instance 0x6833c90
2011-07-29 13:52:52.976 HelloWorld[1031:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString shuffle]: unrecognized selector sent to instance 0x6833c90'
I don't know what's wrong, my
And here is my code.
`#import <Foundation/Foundation.h>
#import "cocos2d.h"
#interface GameScene : CCLayer {
NSMutableArray * answersArray; //holds all valid answers
NSMutableArray * lettersArray; //holds placement of letters to display
NSMutableArray * userAnswerArray; //holds user's answer to check and submit
NSString * THEWORD; //the word
}
+(id) scene;
....
- (void) spinWord;
- (void) playWord;
#end`
And this implementation:
`
#implementation GameScene
+(id) scene { ... }
-(id) init
{
if( (self=[super init])) {
...//everything is initialized
[self initImages]
...
}
}
- (void) initImages
{
....
CCMenuItem *menuItem1 = [CCMenuItemImage itemFromNormalImage:#"PLAYunselected.png" selectedImage:#"PLAYselected.png" target:nil selector:#selector(onPlayWord)];
CCMenuItem *menuItem2 = [CCMenuItemImage itemFromNormalImage:#"SPINunselected.png" selectedImage:#"SPINselected.png" target:self selector:#selector(spinWord)];
CCMenu *menu = [CCMenu menuWithItems:menuItem1, menuItem2, nil];
[menu alignItemsHorizontally];
menu.position = ccp(72, 198);
[self addChild:menu z:2];
}
- (void) spinWord{
//NSLog(#"%#",lettersArray); <---if I uncomment this line, I get an EXC_BAD_ACCESS message instead
[lettersArray shuffle]; // <--- this line causes the SIGABRT signal, even if it's initialized.
NSLog(#"%#",lettersArray);
...
}
#end
`
Please help me out. Is this a memory management problem? If so, how do I fix it?
Thank you very much!
That error always means exactly what it reads like it means. You have sent a message to an object that does not understand that message (meaning the object does not have a method to handle such a request). This however can also mean you are sending a message to an object that does not exist.
If you try to access a bad array index (or the index of an array that does not actually exist) you get bad access. If you try to access a method that does not exist, or a method of an object that does not exist, you get a unrecognized selector message.
I do not see you allocating or initializing your arrays. I don't know what shuffle is, you have not posted code for it. It may be a built in method for all I know. I am fairly certain that all you need to do is allocate and initialize your arrays.
NSMutableArray * answersArray = [[NSMutableArray alloc] init];
// And so on with your other arrays.
I noticed you have target:nil instead of target:self on menuItem1. The error is happening on menuItem2, so I'm not sure that's relevant. I was getting a very similar error just the other day, and it came down to the wrong target. Everything else in your code looks OK to me at first glance.
Related
Hi all you awesome coders! I've put together this thing from various helpful sources over the last couple of weeks (including a lot of posts from stackoverflow), trying to create something that will take a webcam feed and detect smiles when they occur (might as well draw boxes around the faces and the smiles as well, that doesn't seem like it would be hard once they are detected). Please give me some lee-way if it's messy code because I'm still very much learning.
Currently I'm stuck at trying to pass the image to a CIImage so it can be analysed for faces (I plan to deal with smiles after the face hurdle is overcome). As it is the compiler succeeds if I comment out the block after (5) - it brings up a simple AVCaptureVideoPreviewLayer in a window. I think this is what I've called "rootLayer", so it's like the first layer of the displayed output, and after I detect faces in the video frames I'll show a rectangle following the "bounds" of any detected face in a new layer overlaid on top of this one, and I've called that layer "previewLayer"... correct?
But with the block after (5) there, the compiler throws out three errors -
Undefined symbols for architecture x86_64:
"_CMCopyDictionaryOfAttachments", referenced from:
-[AVRecorderDocument captureOutput:didOutputSampleBuffer:fromConnection:] in AVRecorderDocument.o
"_CMSampleBufferGetImageBuffer", referenced from:
-[AVRecorderDocument captureOutput:didOutputSampleBuffer:fromConnection:] in AVRecorderDocument.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Can anyone tell me where I'm going wrong and what my next steps are?
Thanks for any help, I've been stuck at this point for a couple of days and I can't figure it out, all the examples I can find are for IOS and don't work in OSX.
- (id)init
{
self = [super init];
if (self) {
// Move the output part to another function
[self addVideoDataOutput];
// Create a capture session
session = [[AVCaptureSession alloc] init];
// Set a session preset (resolution)
self.session.sessionPreset = AVCaptureSessionPreset640x480;
// Select devices if any exist
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (videoDevice) {
[self setSelectedVideoDevice:videoDevice];
} else {
[self setSelectedVideoDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeMuxed]];
}
NSError *error = nil;
// Add an input
videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
[self.session addInput:self.videoDeviceInput];
// Start the session (app opens slower if it is here but I think it is needed in order to send the frames for processing)
[[self session] startRunning];
// Initial refresh of device list
[self refreshDevices];
}
return self;
}
-(void) addVideoDataOutput {
// (1) Instantiate a new video data output object
AVCaptureVideoDataOutput * captureOutput = [[AVCaptureVideoDataOutput alloc] init];
captureOutput.videoSettings = #{ (NSString *) kCVPixelBufferPixelFormatTypeKey : #(kCVPixelFormatType_32BGRA) };
// discard if the data output queue is blocked (while CI processes the still image)
captureOutput.alwaysDiscardsLateVideoFrames = YES;
// (2) The sample buffer delegate requires a serial dispatch queue
dispatch_queue_t captureOutputQueue;
captureOutputQueue = dispatch_queue_create("CaptureOutputQueue", DISPATCH_QUEUE_SERIAL);
[captureOutput setSampleBufferDelegate:self queue:captureOutputQueue];
dispatch_release(captureOutputQueue); //what does this do and should it be here or after we receive the processed image back?
// (3) Define the pixel format for the video data output
NSString * key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber * value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary * settings = #{key:value};
[captureOutput setVideoSettings:settings];
// (4) Configure the output port on the captureSession property
if ( [self.session canAddOutput:captureOutput] )
[session addOutput:captureOutput];
}
// Implement the Sample Buffer Delegate Method
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
// I *think* I have a video frame now in some sort of image format... so have to convert it into a CIImage before I can process it:
// (5) Convert CMSampleBufferRef to CVImageBufferRef, then to a CI Image (per weichsel's answer in July '13)
CVImageBufferRef cvFrameImage = CMSampleBufferGetImageBuffer(sampleBuffer); // Having trouble here, prog. stops and won't recognise CMSampleBufferGetImageBuffer.
CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
self.ciFrameImage = [[CIImage alloc] initWithCVImageBuffer:cvFrameImage options:(__bridge NSDictionary *)attachments];
//self.ciFrameImage = [[CIImage alloc] initWithCVImageBuffer:cvFrameImage];
//OK so it is a CIImage. Find some way to send it to a separate CIImage function to find the faces, then smiles. Then send it somewhere else to be displayed on top of AVCaptureVideoPreviewLayer
//TBW
}
- (NSString *)windowNibName
{
return #"AVRecorderDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
[super windowControllerDidLoadNib:aController];
// Attach preview to session
CALayer *rootLayer = self.previewView.layer;
[rootLayer setMasksToBounds:YES]; //aaron added
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
[self.previewLayer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
[self.previewLayer setFrame:[rootLayer bounds]];
//[newPreviewLayer setAutoresizingMask:kCALayerWidthSizable | kCALayerHeightSizable]; //don't think I need this for OSX?
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
[rootLayer addSublayer:previewLayer];
// [newPreviewLayer release]; //what's this for?
}
(moved from the comments section)
Wow. I guess two days and one StackOverflow post is what it takes to figure out that I haven't added CoreMedia.framework to my project.
I am coding an app that involves loading data from NSUserDefaults. So when I have confirmed that the passed integer was 1, I want it to display a certain text. However when I don't have a UILabel on my .Xib. It is fine, but as soon as I add a outlet for the label, place it onto the .Xib and link it all up, it comes up with SIGABRT
-(void)viewDidLoad {
int page = [[[NSUserDefaults standardUserDefaults] objectForKey:#"Page"] integerValue];
NSString *log = [NSString stringWithFormat:#"%d", page];
NSLog(log);
if (page == 1 ) {
NSLog(#"redstone block");
title.text = #"redstone Blcok";
}
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
The error I get:
2013-04-09 18:16:13.910 redstoneGuide[94905:c07] -[UILabel copyWithZone:]: unrecognized selector sent to instance 0x756b910
2013-04-09 18:16:13.911 redstoneGuide[94905:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILabel copyWithZone:]: unrecognized selector sent to instance 0x756b910'
* First throw call stack:
(0x1599012 0x12a6e7e 0x16244bd 0x1588bbc 0x158894e 0x12baae9 0x2cd32b 0xcd45be 0xcd40e7 0xcfeb58 0x408019 0x12ba663 0x159445a 0x406b1c 0x2cb7e7 0x2cbdc8 0x2cbff8 0x2cc232 0x2d7c25 0x4d73a3 0x2d4ee3 0x2d5167 0x33cc 0x12ba705 0x1ee2c0 0x1ee258 0x2af021 0x2af57f 0x2ae6e8 0x4b21d3 0x1561afe 0x1561a3d 0x153f7c2 0x153ef44 0x153ee1b 0x25fa7e3 0x25fa668 0x1eaffc 0x1fcd 0x1ef5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
It turns out you cannot do
Iboutlet uilabel *title;
The name title causes the application to crash.
However, the below works.
Iboutlet uilabel *Gtitle
I am attempting to make a basic game which requires a serious of buttons to control player movement. Keep in mind I am using cocos-2d. My goal is to have the buttons be holdable and move a sprite when held down. The code i am using now looks like this.
CCMenuItemHoldable.h
#interface CCMenuItemSpriteHoldable : CCMenuItemSprite {
bool buttonHeld;
}
#property (readonly, nonatomic) bool buttonHeld;
CCMenuItemHoldable.m
#implementation CCMenuItemSpriteHoldable
#synthesize buttonHeld;
-(void) selected
{
[super selected];
buttonHeld = true;
[self setOpacity:128];
}
-(void) unselected
{
[super unselected];
buttonHeld = false;
[self setOpacity:64];
}
#end
and for the set up of the buttons
rightBtn = [CCMenuItemSpriteHoldable itemFromNormalSprite:[CCSprite spriteWithFile:#"art/hud/right.png"] selectedSprite:[CCSprite spriteWithFile:#"art/hud/right.png"] target:self selector:#selector(rightButtonPressed)];
CCMenu *directionalMenu = [CCMenu menuWithItems:leftBtn, rightBtn, nil];
[directionalMenu alignItemsHorizontallyWithPadding:0];
[directionalMenu setPosition:ccp(110,48)];
[self addChild:directionalMenu];
This all seems to work fine but when i do
-(void)rightButtonPressed:(id) sender
{
if([sender buttonHeld])
targetX = 10;
else{
targetX = 0;
}
}
The crash has been fixed but I am trying to get my sprite to move. In my game tick function I add the value of targetX to the position of the sprite on a timer, still no movement.
Please, always include a crash log when asking questions about crashes.
In your case, I can guess the problem. You are adding this selector:
#selector(rightButtonPressed)
Your method is called
rightButtonPressed:(id)sender
Which would be, as a selector, rightButtonPressed: - note the colon indicating that an argument is passed. Either change the method so it has no argument, or add a colon to the selector when you create the button.
The crash log would be telling you this - it would say "unrecognised selector sent to..." with the name of the receiving class, and the name of the selector.
Updated:
I have subclassed UIImageView to make some images movable through touch gestures. In the view controller I have an array holding the initial position of each imageview. My problem is that this array returns null whenever it is called on from the subclass. The idea is to check if the image is in its original position or if it has already been moved before, I have stripped the code to just NSLog what's going on but the problem remains and is driving me nuts.
ViewController.h
NSMutableArray *originalPositions;
#property (nonatomic, retain) NSMutableArray *originalPositions;
-(void)testLogging;
ViewController.m
#synthesize originalPositions;
- (void)viewDidLoad {
originalPositions = [[NSMutableArray alloc]init];
}
-(void)drawImages {
for (int i = 0; i < imagesArray.count; i++) {
CGRect frame = CGRectMake(65 * i, 10, 60, 60);
draggableView *dragImage = [[draggableView alloc] initWithFrame:frame];
NSString* imgName = [imagesArray objectAtIndex:i];
[dragImage setImage:[UIImage imageNamed:imgName]];
[dragImage setUserInteractionEnabled:YES];
[self.view addSubview:dragImage];
NSString *originalPositionAsString = NSStringFromCGPoint(dragImage.center);
[originalPositions addObject:originalPositionAsString];
}
}
-(void)testLogging {
NSLog(#"Logging array: %#", originalPositions);
}
-(IBAction)btnClicked {
[self testLogging];
}
When called from the IBAction (or any other way) in the class, the 'testLogging'-method NSLogs the array correctly but if I call the same method from the subclass, it NSLogs null:
Subclass.m
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
ViewController *viewController = [[ViewController alloc] init];
[viewController testLogging];
}
self.originalPositions = [[NSMutableArray alloc]init];
This already is a memory leak, when you call self.originalPositions = bla then 'bla' will be retained. Thus meaning that the retain count is upped. This means that your mutable array will have a retain count of 2 and that it will leak once your UIImageView is gone.
As for the rest, I wouldn't know what is wrong with your code. My first guess would be that you didn't call populatePositionsArray yet, you should call this whenever your view is created / shown so you are sure the array is populated when touchesBegan is called.
Alternatively you could include an 'if' statement in the touchesBegan that checks whether the array exists and otherwise call the populatePositionsArray to populate it before continueing.
I solved it by writing the array to a plist file after populating it. Not very elegant but working.
Thanks for the help though guys.
I am doing drag and drop with NSView.
In the object to be dragged, which is subclass of NSView, I implemented mouseDown: method as follows:
#try {
NSPoint location;
NSSize size ;
NSPasteboard *pb = [NSPasteboard pasteboardWithName:#"CameraIconContainer"];
location.x = ([self bounds].size.width - size.width)/2 - 21.0;
location.y = ([self bounds].size.height - size.height)/2 - 7.0;
NSLog(#"mouseDown: location- (%f, %f)",location.x,location.y);
NSDictionary *iconViewDict = [[NSDictionary alloc] initWithObjectsAndKeys:[cameraNo stringValue],#"cameraNo",nil];
NSLog(#"iconViewDict - %#",iconViewDict);
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:iconViewDict];
[pb declareTypes:[NSArray arrayWithObject:IconDragDataType] owner:self];
[pb setData:data forType:IconDragDataType];
[self dragImage:[NSImage imageNamed:#"camera_icon.png"] at:location offset:NSZeroSize event:e pasteboard:pb source:self slideBack:YES];
}
#catch (NSException * e) {
NSLog(#"CameraIconView (-mouseDown:), error - %#",e);
}
Most of the time it is working fine but problem is- sometimes it is raising this
exception:Invalid parameter not
satisfying: theWriteStream != NULL
in the mouseDown: method, because of it the dragged image continuously appears over screen, which does not disappear even if some other window is selected.
Can anyone suggest me why is it occurring and how can I resolve it?
Thanks,
Miraaj
exception:Invalid parameter not satisfying: theWriteStream != NULL
That sort of exception comes from an assertion. Something is about to try to write to a stream, and asserted that it has a stream to write to. When the assertion fails, that means that the condition was untrue; in this case, it means that it did not have a stream to write to.
I don't see any stream-related code in the sample you provided, so it's either somewhere else in your app or somewhere within a framework you're using. You should turn on “Stop on Objective-C exceptions” in Xcode, then run your app under the debugger until the exception occurs, then look at the stack trace in the debugger to see exactly what threw the exception.