NSFormatter and NSTokenField and setting the maximum length - objective-c

I would like to use a custom NSFormatter to judge the length of a string inside of a NSTokenField.
I have implemented the NSFormatter and hooked it up within the xib and all that, now when I get to running my application with the formatter inplace connected to the NSTokenField I get this error:
2011-12-31 18:15:11.761 MyApp[4706:a0f] -[NSCFArray length]: unrecognized selector sent to instance 0xf4a530
(gdb) describe 0xf4a530
Undefined command: "describe". Try "help".
(gdb) p 0xf4a530
$1 = 16033072
(gdb) po 0xf4a530
<NSCFArray 0xf4a530>(
{
Format = "%01d";
FormatIndex = 0;
Name = "$Counter$";
},
{
Format = "";
Name = hey;
}
)
Now I understand that indeed the textcell being evaluated contains an array of items so I will need to probably turn these to a string but the place where this is erroring in my code is here:
//Set this so that user can't enter a super long amount and overflow the character array lower in the engine.
[fieldFormatter setMaximumLength:40];
Im just evaluating the fieldFormatter object and setting its member variable of int to 40... really shouldnt be evaluating the text yet... right?

Related

Objective C : Expected Body of Lambda expression

I am working on a small xcode project (my first project) using objective C and am trying to display a variable onto my label in the UI. I have declared the label onto the header file by "ctrl + connecting" it and creating a weak outlet connection but when I try to assign the text value of the label to my variable I get an error saying Expected body of lambda expression
Here is the snippet of the code that throws this error. I essentially want to assign the the variable words as the text for my label:
- (void)speak:(NSString *)words {
NSLog(#"%#", words);
labelForCategory.text = [words];
}
Any suggestions on how to navigate through this will be very helpful. The error is shown on the line labelForCategory.text = [words];
Words is a NSString object so remove [] as
- (void)speak:(NSString *)words {
NSLog(#"%#", words);
labelForCategory.text = words;
}

MKPolygon using Swift (Missing argument for parameter 'interiorPolygons' in call)

Fellow Devs,
I'm trying to implement a polygon overlay on a mapview as follows:
private func drawOverlayForObject(object: MyStruct) {
if let coordinates: [CLLocationCoordinate2D] = object.geometry?.coordinates {
let polygon = MKPolygon(coordinates: coordinates, count: coordinates.count)
self.mapView.addOverlay(polygon)
}
}
The following error is presented:
Missing argument for parameter 'interiorPolygons' in call
According to the documentation:
Apple Docu:
Mutable Pointers
When a function is declared as taking an UnsafeMutablePointer
argument, it can accept any of the following:
nil, which is passed as a null pointer
An UnsafeMutablePointer value
An in-out expression whose operand is a stored lvalue of type Type, which is passed as the address of the lvalue
An in-out [Type] value, which is passed as a pointer to the start of the array, and lifetime-extended for the duration of the call
Now I think that my approach then would be correct, providing a [CLLocationCoordinate2D] array. Did anyone experience the same problem and found a workaround?
thanks
Ronny
The error you're getting is Swift's cryptic way of saying that it can't find a method which matches your parameters. If you did try passing the interiorPolygons parameter, you'd get an equally confusing:
Extra argument 'interiorPolygons' in call
Your code is pretty close though; you just need a couple of minor changes. In the doc you reference, it says one of the things you can pass is:
An in-out [Type] value, which is passed as a pointer to the start of
the array, and lifetime-extended for the duration of the call
So, it's looking for an in-out parameter. Which is done by passing coordinates prefixed with an &, like so:
MKPolygon(coordinates: &coordinates, count: coordinates.count)
But, in-out parameters can't be constants. From the docs:
You can only pass a variable as the argument for an in-out parameter.
You cannot pass a constant or a literal value as the argument, because
constants and literals cannot be modified.
So, you need to define coordinates with a var first:
if var coordinates: [CLLocationCoordinate2D] = object.geometry?.coordinates
Which makes the entire function look like this:
private func drawOverlayForObject(object: MyStruct) {
if var coordinates: [CLLocationCoordinate2D] = object.geometry?.coordinates {
let polygon = MKPolygon(coordinates: &coordinates, count: coordinates.count)
self.mapView.addOverlay(polygon)
}
}
My final solution by cherry-picking from several tutorials and integrating:
func setPolylineFromPoints(locations:[CLLocation]){
if locations.count == 0 {
return;
}
// while we create the route points, we will also be calculating the bounding box of our route
// so we can easily zoom in on it.
var pt : UnsafeMutablePointer<MKMapPoint>? // Optional
pt = UnsafeMutablePointer.alloc(locations.count)
for idx in 0..<locations.count-1 {
let location = locations[idx]
let point = MKMapPointForCoordinate(location.coordinate);
pt![idx] = point;
}
self.polyline = MKPolyline(points:pt!, count:locations.count-1)
// clear the memory allocated earlier for the points
pt?.destroy()
pt?.dealloc(locations.count)
}

Corefoundation CFArray ownership

I found a strange problem while using Core Foundation Array! Here is the code snippet
fname = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%s"), path, ep->d_name);
CFArrayAppendValue(fileNames, fname);
CFRelease(fname); <---- problem here
cnt = CFArrayGetCount(fileNames);
for (i = 0; i < cnt; i++) {
fname = CFArrayGetValueAtIndex(fileNames, i);
if (fname) {
ptr = (char *)CFStringGetCStringPtr(fname, CFStringGetFastestEncoding(fname));
The code crashes at the last line. Please correct me if I got this wrong. After I created the CFStringRef, I add it to CFArray. As per my understanding the object is now owned by CFArray. Hence I can safely remove the CFStringRef I originally allocated. But when I do CFRelease(fname); the code crashes when I access the array elements in the second part of the code. Can someone explain what is correct way of doing it? If I remove the CFRelease() then everything works fine.
As CFMutableArray Reference says:
The value parameter is retained by theArray using the retain callback
provided when theArray was created. If value is not of the type
expected by the retain callback, the behavior is undefined.
So looks like this is the issue of the fileNames array creation. Probably the third parameter of the CFArrayCreateMutable function. Since CFString is a CFType try to pass kCFTypeArrayCallBacks there.

Find out how many arguments a block needs

Let's say I have an array containing Blocks, and I need to assert that all of them expect a given number of arguments.
Is there a way to find this out programmatically?
This is indeed possible, for any recent version of Clang.
The Apple ABI for Blocks is private but also published. Since that document tells us the layout the compiler will use for a Block object, we can duplicate that information in a header file and use it to access the components of a Block.
Mike Ash's MABlockForwarding project does just that (see also the article) -- much of the stuff at the top of this file is a copy-paste from the ABI doc. The thing that he created which we are interested in is the BlockSig() function:
static const char *BlockSig(id blockObj)
{
struct Block *block = (__bridge void *)blockObj;
struct BlockDescriptor *descriptor = block->descriptor;
assert(block->flags & BLOCK_HAS_SIGNATURE);
int index = 0;
if(block->flags & BLOCK_HAS_COPY_DISPOSE)
index += 2;
return descriptor->rest[index];
}
which will return (for Blocks that have it (which they all do with recent Clang)), a type encoding string describing the Block's return and argument types. From there, you can create an NSMethodSignature object, and ask it for its numberOfArguments:
NSString * (^block)(int, NSArray *) = ^NSString * (int i, NSArray * a){
return #"Oh, yeah!";
};
const char * types = BlockSig(block);
NSMethodSignature * sig = [NSMethodSignature signatureWithObjCTypes:types];
[sig numberOfArguments];
The result there is 3, because it includes a hidden argument for the Block itself (and Blocks don't use the hidden _cmd argument or it would be 4).
The answer is you cannot. See the comment on Mike Ash's page regarding this:
Search for Intropection which sends you here
So, what is your real problem? If you structure the arguments properly, you can insure that your system functions properly. For instance, you can do what C++ does with default values for arguments, and cast each block to a type that takes the max number of args, and always push that many items on the stack. Or you could always have the first argument be the number of arguments you are pushing on the stack. If you push objects and not numbers/pointers, then you r blocks can look at the class of each argument and dynamically adapt.

making an apple-scriptable application in Objective C, getting bizarre errors

Ok, so I've got an application, and I want to make it scriptable. I set up the plist, I set up the sdef file.
So far I have only one apple Event command: gotoPage. it takes an integer. and returns a boolean.
The relevant XML is:
<command name="gotoPage" code="dcvwgoto" description="Goto a specified page">
<cocoa class="AEGoto"/>
<direct-parameter description="Page Number" type="integer"/>
<result description="True if the page exists, False othrewise" type="boolean"/>
</command>
I have an Objective-C class AEGoto.h:
#interface AEGoto :NSScriptCommand {
}
- (id)performDefaultImplementation;
- (id)performDefaultImplementation
{
int page = [[self directParameter] intValue];
Boolean retval = [gController setPage: page];
return retval? #"YES" : #"NO";
}
setPage: (int) is correct, and works fine.
When I call this, my program seems to work correctly. But then I get the error:
error "DocView got an error: 4 doesn’t understand the gotoPage message." number -1708 from 4
I also get, in my DocView output:
Error while returning the result of a script command: the result object... YES ...could not be converted to an Apple event descriptor of type 'boolean'. This instance of the class 'NSCFString' doesn't respond to -scriptingBooleanDescriptor messages.
However, if I return just the straight Boolean, I get:
Single stepping until exit from function -[NSScriptingAppleEventHandler handleCommandEvent:withReplyEvent:],
which has no line number information.
Program received signal: “EXC_BAD_ACCESS”.
so, I guess I've got 2 questions: 1) Why does it think it wants to tell 3 to goto a page? and 2) what is the correct way to return a Boolean from the applescript?
thanks.
return [NSNumber numberWithBool:retval];