I'm trying to send some data from a swift file to an objective-c file. I have all the bridging headers and whatnot configured, such that when I pass a string, it can be used by the objective-c file. However, I would really like to pass an NSArray, and when I do this, I get a whole slew of errors starting with
[Swift._NSSwiftArrayImpl length]: unrecognized selector sent to instance 0x6000000363a0
I saw Array element cannot be bridged to Objective-C but solutions on that page, which were switching the Array to an NSArray in swift, and making all the objects in the array AnyObjects, did not work; besides, the error I got is different from the error on the aforementioned question. This is my condensed code:
Swift:
var myNSArray = ["foo","bar"]
objectiveCClassInstance.arrayPassFunction(myNSArray)
.h:
- (void)arrayPassFunction:(NSArray*)myObjectiveCNSArray;
.m:
- (void)arrayPassFunction:(NSArray*)myObjectiveCNSArray{
NSLog(myObjectiveCNSArray);
}
Your call to NSLog is incorrect. The first parameter of NSLog is the format string. You meant:
NSLog(#"%#", myObjectiveCNSArray);
I'm surprised you didn't get a warning about this.
Related
Customizing an iOS app in objective-c. Not super familiar with the language, and this simple task of setting up a boolean property has taken me too long.
Can anybody offer some advice here?
Video.h
#property (nonatomic, retain) NSNumber * hasCustomThumbnail;
Video.m
#implementation Video
#dynamic hasCustomThumbnail;
#end
OtherFile referencing the video
// have tried these two an many other things...
video.hasCustomThumbnail = [NSNumber numberWithBool:NO];
video.hasCustomThumbnail = #NO;
The error I get no matter how many dozens of ways I've tried this is:
'NSInvalidArgumentException', reason: '-[Video setHasCustomThumbnail:]: unrecognized selector sent to instance 0x60c0004925c0'
Have tried many suggestions including this: Using a BOOL property
I also know the video is referenced correctly because autocomplete suggests "hasCustomThumbnail" as I start typing.
I simply cannot believe how hard OBJ-c is making this :-)
Any suggestions?
The issue is that you have declared it as #dynamic. Just remove this line from the Video.m. Xcode will automatically synthesize the getters and setters.
either of this works.
[obj setHasCustomThumbnail:[NSNumber numberWithBool:true]];
obj.hasCustomThumbnail = [NSNumber numberWithBool:true];
#dynamic just tells the compiler that the getter and setter methods
are implemented not by the class itself but somewhere else (like the
superclass or will be provided at runtime).
#synthesize will generate getter and setter methods for your property.
So when you define a property with #dynamic, either your superclass or runtime should provide the necessary getter and setter. here no one has provided anything, that is the reason it is saying the unrecognized selector sent to an instance. This error will come only if it couldn't able to find a proper method for the object. Hope this will clear your doubts.
one practical use of #dynamic is that when you inherit your class from
NSManagedObject, the core data will provide the setter and getters for
the properties.
This problem is not related to BOOL or NSNumber. It is due to your calling setIsCustomThumbnail on class Video.
Either you are doing video.isCustomThumbnail = or [video setIsCustomThumbnail:] but your class does not declare this isCustomThumbnail. From your code seems you mispelled isCustomThumbnail as hasCustomThumbnail.
So make up your mind and use single name.
I'm new to objective-c and xcode and an app I'm currently writing is receiving the infamous EXC_BAD_ACCESS error.
Almost everybody recommends starting to solve the problem using NSZombies. I think I have NSZombies working but xcode isn't giving me an alert about a zombie being messaged when my app crashes.
Before I move on with my debugging, I'd like to run some code that should for sure result in a message being sent to a zombie (de-allocated object).
What is a simple code snippet where a message is sent to a deallocated object, causing a scenario where NSZombies should alert me?
For non-ARC code:
- (IBAction) messageZombie:(id)sender {
id a = [[NSObject alloc]init];
[a release];
NSLog(#"%#", [a description]);
}
This will give you EXC_BAD_ACCESS with Zombies off, and a "message sent to deallocated instance" message, with Zombies enabled.
If your project is using ARC, then it's a bit harder to reliably-cause messages to de-allocated objects (that is the point of ARC, after all).
This works:
- (IBAction) messageZombie:(id)sender {
id a = [[NSObject alloc]init];
id __unsafe_unretained b =a;
a=nil;
NSLog(#"%#", [b description]);
}
It's probably not very similar to what your actual code is doing, because who the heck uses __unsafe_unretained, anyway? But if you just want to make sure that you've got NSZombies turned on properly, this should be a reasonable test case.
If you're looking for suspicious places in your code, then for sure look for __unsafe_unretained pointers, though you won't find any*, and double-check that the right casts are used for CoreFoundation objects that are casted to Cocoa objects.
* If your project needs to support OS X versions before 10.7, or iOS versions earlier than 5.0, then you can't use __weak pointers, so in that sort of project, you'd expect to find __unsafe_unretained used more often.
You could create a CF object, bridge it to an Objective-C object, then release it and try to use the bridged object. I think you have to use __bridge to get this to behave the way you want.
I'm tearing my hair out trying to do the simplest of tasks... subclassing an NSAttributedString. Trying to call the super class's initWithAttributedString: method is causing an unrecognized selector sent to instance error.
MODAttributedString.h:
#import <Foundation/Foundation.h>
#interface MODAttributedString : NSAttributedString
#property (nonatomic, retain) NSDictionary *links;
+ (MODAttributedString*) attributedStringWithFormat:(NSString*)text args:(id)argOne, ... NS_REQUIRES_NIL_TERMINATION;
+ (MODAttributedString*) attributedStringWithFormat:(NSString*)text attributes:(NSDictionary*)attributeDict;
#end
The code that is causing the crash (I'll explain the reason I split the alloc from the init in a moment):
MODAttributedString *modString = [MODAttributedString alloc];
// Pausing debugger here and typing 'po modString' causes gdb error
modString = [modString initWithAttributedString:attributedString];
My only clue is that stepping over the alloc call, when I try to po modString, I'm given this error:
"The program being debugged hit an ObjC exception while in a function called from gdb.
If you don't want exception throws to interrupt functions called by gdb
set objc-exceptions-interrupt-hand-call-fns to off.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off"
Evaluation of the expression containing the function (_NSPrintForDebugger) will be abandoned."
If I temporarily change the super class of MODAttributedString to a UIView, the alloc does not cause the gdb error (I stop the debugger prior to the init, which would obviously not work for anything other than an attributed string). However, common classes like NSArray, NSDictionary and NSAttributedString all fail with the same error.
In the method that calls the [MODAttributedString alloc] I use NSAttributedString as its own standalone class just fine. I am sure I'm including the MODAttributedString header in this .m file as well.
I'm using Xcode 4.2 and the iPhone 5 simulator. I've cleaned the project multiple times, tried creating a new project, tried using both LLVM GCC 4.2 and Apple LLVM 3.0, restarted Xcode and restarted my machine all to no success. I searched for this particular issue heavily before posting, but I only found issues related to properties, never to a superclass's public methods.
Is this a build settings issue? A configuration error? A compiler bug? I've subclassed common Apple classes hundreds of times, and for some reason this is the first time I've ever had an issue. Has anyone else ever had a similar problem? It's probably a really simple fix, but I just can't seem to figure it out on my own.
Thanks in advance!
It isn't "the simplest of things". You can't subclass NSAttributedString - it's part of a class cluster. This means (among other things) that the class returned when you instantiate is not necessarily the class you asked for. See What exactly is a so called "Class Cluster" in Objective-C?
It is possible, with great pain and difficulty, to subclass within a class cluster, but my advice is to write a wrapper class instead; you'll be much happier. Cocoa's dynamic redirection of unhandled methods makes this very easy.
I've just come across some code in Three20 that looks like this:
SEL sel = #selector(textField:didAddCellAtIndex:);
if ([self.delegate respondsToSelector:sel]) {
[self.delegate performSelector:sel withObject:self withObject:(id)_cellViews.count-1];
}
On LLVM 2.0, this causes the compilation error:
error: arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI
I know why that error is occurring and I know how to fix it. I just need to invoke the method directly, like so:
SEL sel = #selector(textField:didAddCellAtIndex:);
if ([self.delegate respondsToSelector:sel]) {
[self.delegate textField:self didAddCellAtIndex:(_cellViews.count - 1)];
}
My question is, if you know both the selector and its arguments at compile time, why would you need to use performSelector:withObject:withObject: at runtime? I don't see why the code was written this way in the first place. If the selector and arguments were dynamically passed into the method, I may understand, but they're not, the selector and its arguments are hard coded, (even if the index does change during run time, its method of obtaining the index is hard coded.)
If someone could explain to me a good reason why this would be necessary, I'd be grateful. Otherwise, I'll be over here changing all this code.
After a little more digging, it looks like the TTPickerTextField class that this code is found in is an indirect subclass of a UITextField.
As such, it is piggy-backing on UITextFields delegate property, which doesn't conform to the TTPickerTextFieldDelegate protocol where the method textField:didAddCellAtIndex: is declared.
I have come to the conclusion that this code is just laziness. No reason why the UITextFields delegate property had to be piggy-backed, making this confusing, error prone code necessary.
My own approach would have been to leave UITextFields delegate property alone, and add my own property in my specific subclass that handled the specific delegate methods.
Just to clarify - the 'solution' I mentioned in the question fixes the compiler error, but generates a warning that the method can't be found and will be assumed to return id. This is what the original code was 'solving' but that only worked in GCC. No longer with LLVM 2.0.
Last edit, I promise:
My final solution to combat this laziness and get rid of the warning and error is an ugly hack:
[(id <TTPickerTextFieldDelegate>)self.delegate textField:self didAddCellAtIndex:(_cellViews.count - 1)];
Cast UITextFields delegate to an id that conforms to TTPickerTextFieldDelegate and then invoke the method directly.
Please don't be lazy :(
That respondsToSelector/performSelector combo is an idiom for optional delegate methods. The delegate isn't guaranteed to have that method defined, so a direct call to it would cause a compiler warning.
What the compiler was actually complaining about in this case:
[self.delegate performSelector:sel withObject:self withObject:(id)_cellViews.count-1];
error: arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI
is risky pointer arithmetic... 'id' is a pointer type, so:
(id)_cellViews.count-1
tells the compiler it's going to subtract one from a pointer instead of an integer....which is probably not the intent of that code. The withObject argument of performSelector has to be a pointer, it can't be a primitive. You can get around this by wrapping _cellViews.count - 1 in an NSNumber, and unwrapping it in the delegate method.
[self.delegate performSelector:sel withObject:self withObject:[NSNumber numberWithInt:_cellViews.count-1]];
My iphone app crashes with the following error message:
2010-07-26 16:27:30.402 Nav[814:207]
* -[UITextField isNaturallyRTL]: unrecognized selector sent to instance
0x3947fe0 2010-07-26 16:27:30.403
Nav[814:207] * Terminating app due
to uncaught exception
'NSInvalidArgumentException', reason:
'*** -[UITextField isNaturallyRTL]:
unrecognized selector sent to instance
0x3947fe0'
I can't find the text isNaturally RTL in my program. Any ideas on how to find the bug?
It seems that isNaturallyRTL is an (undocumented) NSString method. At least NSString responds to it.
This may mean that you assign a UITextField to some variable, where you should put in an NSString instead.
BTW: 0x3947fe0 is the pointer to the UITextField that should be an NSString, so if you're totally lost, try to find out which UITextField has that address (e.g. by a dumb NSLog("tf X: 0x%x",tfx);)
I found the problem. It was in this line of code:
[tempValues setObject:textFieldBeingEdited forKey:tagAsNum];
I changed it to the following:
[tempValues setObject:textFieldBeingEdited.text forKey:tagAsNum];
and that's what fixed it.
It's because your UITextField object is somehow assigned to a variable/property which is not supposed to be a UITextField.
It can happen in many different ways.
You might have connected the IB outlet incorrectly. Check your nib in the Interface Builder to see your UITextField is not connected to something strange.
You might have just assigned an UITextField to a variable of a different type. In that case, the compiler should have given you a warning. Correct your code and remove all the warnings.
You might have not correctly done retain/release. Do "build and analyze", and remove all warnings.