Too many argument calls to method - objective-c

In xCode when i debug using po i get this error.
(lldb) po [NSString stringWithFormat:#"tel:%#",item.CNUMBER]
error: too many arguments to method call, expected 1, have 2
Some questions that i looked at but doesnt help me.
Too many arguments to method call expected 1, have 2
Too many arguments to method call
Too many arguments to method call, expected 1, have 2?(Xcode)
I even had a moment where i questioned my sanity and went to apples documentions. https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
[NSString stringWithFormat:#"Long %C dash", 0x2014]; // from apples doc
and the results are the same...
(lldb) po [NSString stringWithFormat:#"Long %C dash", 0x2014];
error: too many arguments to method call, expected 1, have 2
im using macOS 10.12.4 and xCode 8.3.2. I even reinstalled xCode from scratch. Any ideas what can be causing this!?
e: using po item.CNUMBER gives me the phone number like its supposed to
item is just a model i use to parse a json response, no methods involved.
LeasesModel *item; // declared as an instance var
...
#interface LeasesModel : NSObject
#property(nonatomic, strong) NSString *ID, *PROPERTYNAME, *ADDRESS1, *ADDRESS2, *CITY, *STATE, *ZIP, *WBPOINT, *COMMENTS, *CNAME, *CNUMBER, *CEMAIL, *CCOMPANY, *ISRETAILSPACE, *ISOFFICESPACE, *ISCOMMUNITYFACILITY, *SQFT, *STATUS, *ASKINGRENT, *FLOORCOUNT, *FLOOR1SF, *FLOOR1ASKING, *FLOOR2SF, *FLOOR2ASKING, *FLOOR3SF, *FLOOR3ASKING, *FLOOR4SF, *FLOOR4ASKING, *FLOOR5SF, *FLOOR5ASKING;
#end
e: i was unable to reproduce the error in a new project.

Thanks to #danh, we figured out the issue with was a NSString extension method. Removing it allowed me to debug like normal.

Related

How to make Xcode produce error or warning in case of generic type mismatch?

Please consider the following:
#interface Test : NSObject
+ (void)testBlock:(void(^)(NSArray<NSString*>*))aBlock;
#end
#implementation Test
+ (void)testBlock:(void (^)(NSArray<NSString *> *))aBlock
{
aBlock(#[#"Hello", #"World"]);
}
#end
and then:
[Test testBlock:^(NSArray<NSNumber*>* arr){
[arr.firstObject unsignedIntegerValue];
}];
it's a crash, but the compiler doesn't even think to warn me, whereas I would like to get an error. Is it even possible? Is there some relevant Clang error or warning I could enable in Xcode in order to make it safer?
UPDATE. I don't want to create another question with a very similar problem. This is really annoying. Take a look:
NSArray<NSString*>* strings = #[#"Hello"];
for (NSNumber* num in strings)
{
[num unsignedIntegerValue];// unrecognized selector crash!!!!
}
Not even a warning. What the ...? It's so easy to leave such a code untouched during refactoring. I would really like to make compiler warn me about cases like this one.

Sematice Issue Property "customUserAgent" not found on object type

I am new to objective c but I have an app I was compiling and it's throwing errors on xcode 6. Any time I click archive the build fails and points to wkWebview.customUserAgent saying that Property not found on object type customUserAgent is not found on type WKWebview. I have combed the web in search of solutions but I couldn't find. I am guessing that customUserAgent was not explicitly defined and I don't simply don't know how to. I'll appreciate any pointer.
// re-create WKWebView, since we need to update configuration
WKWebView* wkWebView = [[WKWebView alloc] initWithFrame:self.engineWebView.frame configuration:configuration];
wkWebView.UIDelegate = self.uiDelegate;
self.engineWebView = wkWebView;
if (IsAtLeastiOSVersion(#"9.0") && [self.viewController isKindOfClass:[CDVViewController class]]) {
wkWebView.customUserAgent = ((CDVViewController*) self.viewController).userAgent;
Please help.
Issue is that you are calling property that is defined in latest version of OS. As you mentioned you are using Xcode 6, try this code with Xcode 7+. Check Frameworks-> WebKit.framework-> Headers-> WKWebView.h-> Line 229
/*! #abstract The custom user agent string or nil if no custom user
agent string has been set.
*/ #property (nullable, nonatomic, copy) NSString *customUserAgent API_AVAILABLE(macosx(10.11), ios(9.0));

Objective-C method parameter type-safety

If I have methods like:
- (BOOL)isValidRow:(NSDictionary*)contentVersionRow
do we really have to continually check like this at the beginning of the method
if(![contentVersionRow isKindOfClass:[NSDictionary class]]) {
// Handle unusual situation - probably return NO in this case
}
to really implement proper type-safety inside Objective-C methods? Because in theory the parameter is not guaranteed to point to an NSDictionary object, is this correct?
EDIT: So answers so far seem to indicate we should not check for this, but then what is the difference between checking for this and checking for nil parameter, which I assume we should do? Or should we not check for nil either, if it's not normally expected? Both cases cover the situation of a misbehaving caller.
Just like in C you are dealing with pointers in Objective-C. So saying NSDictionary * simply means "here's a pointer to a memory address that contains an instance of NSDictionary".
Example:
#import <Foundation/Foundation.h>
#interface Test : NSObject
- (void)useDictionary:(NSDictionary *)dictionary;
#end
#implementation Test
- (void)useDictionary:(NSDictionary *)dictionary
{
NSLog(#"Keys: %#", [dictionary allKeys]);
}
#end
int main(int argc, char *argv[]) {
#autoreleasepool {
Test *test = [[Test alloc] init];
// 1: This works fine
[test useDictionary:#{#"key": #"value"}];
// 2: This will cause a compiler warning (or error depending on the options passed to the compiler)
[test useDictionary:#"not a dictionary"];
// 3: This will compile without any warnings
[test useDictionary:(NSDictionary *)#"not a dictionary"];
}
}
The 2nd and 3rd examples will cause the program to crash at runtime. So if you want to pass incorrect things to methods, you can. Usually Xcode will warn you if you have a type-mismatch.
Update about nil-checking: If it's an API-misuse to pass nil to your method, then throw an exception. That's what exceptions are for in Objective-C: to catch programming mistakes, not to handle expected runtime issues (like an unreachable network). If your method can just silently fail if nil is passed in or handle it in a sensible way, then do that instead. For example if you have a method addValue:(NSNumber *)number that adds the given value to a sum then it wouldn't be a big deal if someone called it with nil: Just don't add anything :)
Yes, but you shouldn’t.
Obj-C is a dynamic language, so it is up to each object to determine if it responds to a certain method. It is bad style to check the class of an object.
Instead, if you want to check that an object supports a selector you should use -respondsToSelector:, but only if you handle objects not responding to that selector.

Objective C MKMapView EXC_BAD_ACCESS

I'm a novice ObjC programmer (started learning last week); I'm having some unexpected results trying to get the lat and long from the centre of an MKMapView.
I have the following method that gets called when the map changes region:
- (void)mapView:(MKMapView*)mapView regionDidChangeAnimated:(BOOL)animated {
NSLog(#"------> %#", mapView);
latLabel.text = [[NSString alloc] initWithFormat:#"%#", [mapView centerCoordinate]];
}
In the log I'm not getting (null), I'm getting the printout of an MKMapView object; but on the very next line I get an unhandled EXC_BAD_ACCESS.
Any help appreciated, and I'd be happy to offer more info if it's requested.
Thanks.
CLLocationCoordinate2D is not an Objective-C object, it's a C structure. You can't directly convert it to an NSString like that.
Try:
CLLocationCoordinate2D center = [mapView centerCoordinate];
latLabel.text = [NSString stringWithFormat:#"(%f, %f)", center.latitude, center.longitude];
Edit: Since you're new to Objective-C, thought you might like some insight into how this problem occurs and why the error message is so non-descriptive.
[NSString stringWithFormat:...] takes a format string and an arbitrary number of parameters. It then parses the format string and fills in the parameters as they're needed.
The %# token in the format string designates an Objective-C object; i.e. an NSObject * or subclass thereof. NSObject defines the description method that provides an NSString * description of the object. stringWithFormat: calls description on the argument provided for the %# token to fill it in the format string.
The result of this is a call is made to objc_msgSend with your CLLocationCoordinate2D struct to make the description call because NSString assumes you've provided the right kind of parameter. Then the crash occurs because objc_msgSend treats the struct as if it's an NSObject * pointer and tries to access memory at a bad location. Hence the EXC_BAD_ACCESS.
Disclaimer: This is based on my understanding of Objective-C after only a couple of years, so if I'm wrong about anything, feel free to correct me.

BOOL not setting correctly, debug output is confusing

I am trying to set a BOOL within Xcode and for some reason it is plain refusing to work. Nothing else is setting this bool, just this one instance. My code is below:
.h
#interface SuspectsViewController : UIViewController
{
BOOL boolContentChanged;
}
#property (nonatomic) BOOL boolContentChanged;
.m
#synthesize boolContentChanged;
-(IBAction)buttonPressed:(id)sender
{
boolContentChanged = true;
}
I have also tried using self.boolContentChanged but nothing happens either. To try and debug this I used po boolContentChanged and get the following output, the first po is before boolContentChanged = true and the second is after.
(lldb) po boolContentChanged
(BOOL) $4 = '\0' <nil>
(lldb) po boolContentChanged
(BOOL) $7 = '\0' <nil>
Does the $ indicate that it's pointing to a certain address, or is that purely for debugging reference?
Also, is there any reason this would be nil? Surely it doesn't need implicitly setting if it is a bool and not a pointer?
Any advice on this is much appreciated as I can't work it out,
Thanks in advanced,
Elliott
"po" in the debugger (gdb) is short for "print-object". The BOOL type is not an Objective-C object. Use "p" or "print" to display the value of BOOL, int, char, etc.
The dollar-number ("$4") output by the debugger in response to your "po" command is assigning the result to a variable in the debugger which you can use in later commands.
As to the problem you describe, can you confirm that your action method is actually getting invoked? Try adding:
NSLog( #"In %#", NSStringFromSelector( _cmd ));
to your -buttonPressed method. If your action is actually getting invoked, you'll see this in the debugger:
In buttonPressed:
You can also have the NSLog() output the values of your BOOL:
NSLog( #"Before: %d", (int)boolContentChanged );
I finally managed to figure out what was happening. In regards to the debugger it did make a practical difference using YES / NO as opposed to true / false, the values were still being set if I used p to explicitly find them, but when using YES / NO they would show automatically. So once again it seems to be the intellisense that is failing to update in certain situations.
Thanks for the help all.
When you use BOOL you need to use YES or NO not true and false.