Most of the assertions I write are based on a conditional expression, like so:
NSParameterAssert(key != nil);
NSAssert(count <= MAX_FACTOR_COUNT, #"Too many factors");
NSAssert1(size % 2 == 1, #"Cannot create hexagonal board with even size %i", size);
But I also have quite a few cases of triggering an assertion failure with a hard-coded false value:
NSAssert(false, #"Abstract method invoked");
NSAssert(false, #"Unimplemented");
NSAssert(false, #"Invalid operation for this subclass");
This feels wrong to me. I feel like I should be saying something like this instead:
NSAssertFail(#"Abstract method invoked");
NSAssertFail(#"Unimplemented");
NSAssertFail(#"Invalid operation for this subclass");
My question is: How have people traditionally dealt with this? What do you name a preprocessor macro that wraps NSAssert(false, ...)?
Is NSAssertFail() a good name?
Related
I'd like to refer variable which I define inside of if block at outside of if else block. How can I? If it can't be, do I have to write same long code (they can't be function or method) inside if block and else block?
if (aTrack.compilation)
{
NSString *artistName = NSLocalizedString(#"compilations", #"");
}
else
{
NSString *artistName = aTrack.artist
}
NSLog(#"%#",artistName);
What #nickfalk and #CRD posted is good but you can also (for such easy statements) use a ternary operator which in this case will look like this:
NSString *artistName = aTrack.compilation ? NSLocalizedString(#"compilations", #""): aTrack.artist;
NSLog(#"%#",artistName);
It is a matter of style but I would go this way for this simple example as my code is in one line
The lifetime of an ordinary (non static) variable declared in a block is just that block, any nested blocks, etc. This is part of the standard lifetime and visibility rules of (Objective-)C(++).
Just declare the variable before the if/else and assign values to it in each block.
This will do what you want:
NSString *artistName;
if (aTrack.compilation){
artistName = NSLocalizedString(#"compilations", #"");
} else {
artistName = aTrack.artist;
}
NSLog(#"%#",artistName);
Also have a look at CRD's reply as this is really basic knowledge and you really need to understand this. (Also, as viperking noticed in my example, there was a terminating semicolon missing in your original code...)
Viperking has a nice example using the the ternary operator. It might be a bit alien at first but is rather nice when you wrap your head around it. a third solution would be
NSString *artistName = aTrack.artist;
if (aTrack.compilation){
artistName = NSLocalizedString(#"compilations", #"");
}
NSLog(#"%#",artistName);
For more complex scenarios I would advice against it, but for an example with two possible cases and one single string it would be quite legible. I'd also advice using nil rather than an empty-string for the localizedString comment.
EDIT: The issue was with the assert as people pointed out below. Thanks for the help!
I have a enum set that i'm trying equate, but for some reason its not working.
Its declared like so:
typedef NS_ENUM(NSUInteger, ExUnitTypes) {
kuNilWorkUnit,
kuDistanceInMeters,
//end
kuUndefined
};
And i'm using it here:
+(NSString*) ExUnitDescription: (ExUnitTypes) exUnit
{
if (exUnit == kuNilWorkUnit)
{
assert("error with units");
}
///.... more stuff
}
Xcode isnt triggering my assert. EDIT: the assert is just for testing. i've used NSLog as well. The conditional isn't evaluating to true even though the value is clearly kuNilWorkUnit.
Does anyone have any suggestions or ideas of what i'm doing wrong?
You want to do this:
+(NSString*) ExUnitDescription: (ExUnitTypes) exUnit
{
assert(exUnit != kuNilWorkUnit);
///.... more stuff
}
This is because, assert only stops execution if the expression you pass to it is false. Since a string literal is always non-zero, it will never stop execution.
Now, since you are using Objective C and it also looks like you want to have a message associated with your assert, NSAssert would be preferable.
+(NSString*) ExUnitDescription: (ExUnitTypes) exUnit
{
NSAssert(exUnit != kuNilWorkUnit, #"error with units");
///.... more stuff
}
I've run into a situation while using a library called TransitionKit (helps you write state machines) where I am want to supply entry and exit actions in the form of a callback.
Sadly, the callbacks include two completely useless parameters. A typical block has to look like this:
^void (TKState *state, TKStateMachine *stateMachine) {
// I TOTALLY don't want parameters `state` or `stateMachine` used here
};
(this is an anonymous code block. Read up on blocks here if you're unclear)
As I've noted in the comment, I really don't want those parameters even mentioned in the body there. I've tried simply removing the parameter names like suggested in this question like so:
^void (TKState *, TKStateMachine *) {
// I foobar all I like here
};
but sadly the code won't compile then :(.
How can I enforce this non-usage of parameters in code?
This is what I could come up with. Quite a hack and relies on the GCC poison pragma, which is not standard but a GNU extension - although, given that you are probably compiling this with clang anyway, it should not be a problem.
#define _state state
#define _stateMachine stateMachine
#pragma GCC poison state stateMachine
Then this compiles:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something();
}
But this doesn't:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something(state, stateMachine);
}
You could just have a function that took one kind of block, and returned another, like this:
#class TKState, TKStateMachine; // here so this will compile
typedef void (^LongStateBlock)(TKState *state, TKStateMachine *stateMachine);
static inline LongStateBlock Adapter(void(^block)()) {
void(^heapBlock)() = [block copy]; // forces block to be on heap rather than stack, a one-time expense
LongStateBlock longBlock = ^(TKState *s __unused, TKStateMachine *sm __unused) {
heapBlock();
};
// this is the non-ARC, MRR version; I'll leave ARC for the interested observer
[heapBlock release];
return [[longBlock copy] autorelease];
}
And in practice:
// this represents a library method
- (void)takesLongStateBlock:(LongStateBlock)longBlock
{
// which hopefully wouldn't look exactly like this
if (longBlock) longBlock(nil, nil);
}
- (void)yourRandomMethod
{
[self takesLongStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
NSLog(#"Gratuitous parameters, AAAAHHHH!");
}];
[self takesLongStateBlock:Adapter(^{
NSLog(#"So, so clean.");
})];
}
The whole thing is gisted, and should compile inside any class. It does what you expect when you call -yourRandomMethod.
AFAIK there is no way to do what you want when you are creating a block, you can only miss the parameter names when you are declaring a block variable(a reference to a block, to avoid misunderstandings)
So here you can miss the param names:
void (^myBlock)(SomeClass *);
But not when you create a block:
myBlock = ^(SomeClass *o)
{
};
I'd write
^void (TKState *unused_state, TKStateMachine *unused_stateMachine) {
// Anyone using unused_state or unused_stateMachine gets what they deserve.
};
Of course someone can use the parameters. But then whatever you do, they can change the code. If someone is intent on shooting themselves in the foot, there is no stopping them.
I am currently writing a program to help me control complex lights installations. The idea is I tell the program to start a preset, then the app has three options (depending on the preset type)
1) the lights go to one position (so only one group of data sent when the preset starts)
2) the lights follows a mathematical equation (ex: sinus with a timer to make smooth circles)
3) the lights respond to a flow of data (ex midi controller)
So I decided to go with an object I call the AppBrain, that receive data from the controllers and the templates, but also is able to send processed data to the lights.
Now, I come from non-native programming, and I kinda have trust issues concerning working with a lot of processing, events and timing; as well as troubles with understanding 100% the Cocoa logic.
This is where the actual question starts, sorry
What I want to do, would be when I load the preset, I parse it to prepare the timer/data receive event so it doesn't have to go trough every option for 100 lights 100 times per second.
To explain more deeply, here's how I would do it in Javascript (crappy pseudo code, of course)
var lightsFunctions = {};
function prepareTemplate(theTemplate){
//Let's assume here the template is just an array, and I won't show all the processing
switch(theTemplate.typeOfTemplate){
case "simpledata":
sendAllDataTooLights(); // Simple here
break;
case "periodic":
for(light in theTemplate.lights){
switch(light.typeOfEquation){
case "sin":
lightsFunctions[light.id] = doTheSinus; // doTheSinus being an existing function
break;
case "cos":
...
}
}
function onFrame(){
for(light in lightsFunctions){
lightsFunctions[light]();
}
}
var theTimer = setTimeout(onFrame, theTemplate.delay);
break;
case "controller":
//do the same pre-processing without the timer, to know which function to execute for which light
break;
}
}
}
So, my idea is to store the processing function I need in an NSArray, so I don't need to test on each frame the type and loose some time/CPU.
I don't know if I'm clear, or if my idea is possible/the good way to go. I'm mostly looking for algorithm ideas, and if you have some code that might direct me in the good direction... (I know of PerformSelector, but I don't know if it is the best for this situation.
Thanks;
I_
First of all, don't spend time optimizing what you don't know is a performance problem. 100 iterations of the type is nothing in the native world, even on the weaker mobile CPUs.
Now, to your problem. I take it you are writing some kind of configuration / DSL to specify the light control sequences. One way of doing it is to store blocks in your NSArray. A block is the equivalent of a function object in JavaScript. So for example:
typedef void (^LightFunction)(void);
- (NSArray*) parseProgram ... {
NSMutableArray* result = [NSMutableArray array];
if(...) {
LightFunction simpledata = ^{ sendDataToLights(); };
[result addObject:simpleData];
} else if(...) {
Light* light = [self getSomeLight:...];
LightFunction periodic = ^{
// Note how you can access the local scope of the outside function.
// Make sure you use automatic reference counting for this.
[light doSomethingWithParam:someParam];
};
[result addObject:periodic];
}
return result;
}
...
NSArray* program = [self parseProgram:...];
// To run your program
for(LightFunction func in program) {
func();
}
I'm putting together a Mac OS X Application and I'm trying to register to receive Display Reconfiguration notices, but I'm very lost right now. I've been reading Apple's documentation and some forums posts, etc., but everything seems to assume a better knowledge of things than I apparently possess. I understand that I have to request the callback inside a run loop for it to work properly. I don't know how to set up a basic run loop for it, though. I also feel like the example Apple has in their documentation is missing stuff they are expecting me to already know. To display my ignorance here is what I feel like things should look like.
NSRunLoop *rLoop = [NSRunLoop currentRunLoop];
codeToStartRunLoop
void MyDisplayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
{
if (flags & kCGDisplayAddFlag) {
NSLog (#"Display Added");
}
else if (kCGDisplayRemoveFlag) {
NSLog (#"Display Removed");
}
}
CGDisplayRegisterReconfigurationCallback(MyDisplayReconfigurationCallBack, NULL);
The actual code I got was from Apple's Example, but it tells me that flags is an undeclared identifier at this point and won't compile. Not that it would work right since I don't have it in a run loop. I was hoping to find a tutorial somewhere that explains registering for system callback in a run loop but have not been successful. If anyone could point me in the right direction I'd super appreciate it.
(I'm sure that you'll be able to tell from my question that I'm very green. I taught myself Objective-C out of a book as my first programming language. I skipped C, so every once in a while I hit a snag somewhere that I can't figure out.)
If you're writing a Mac OS X application, the AppKit has already set up a run loop for you, so you don't need to worry about that part. You really only need to create your own run loop in Cocoa when you are also creating your own thread.
For the "undeclared identifier" part, it looks like it's due to a typo/syntax mistake:
void MyDisplayReconfigurationCallBack (CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
// Semicolon makes this an invalid function definition^^
{
// This is an anonymous block,* and flags wasn't declared in it
if (flags & kCGDisplayAddFlag) {
// etc.
}
Also, unlike some other languages, you can't declare or define functions inside of other functions, methods, or blocks* -- they have to be at the top level of the file. You can't put this in the same place where you call CGDisplayRegisterReconfigurationCallback.
Just as an sample (I have no idea what the rest of your code really looks like):
// MyClassThatIsInterestedInDisplayConfiguration.m
#import "MyClassThatIsInterestedInDisplayConfiguration.h"
// Define callback function at top level of file
void MyDisplayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo)
{
if (flags & kCGDisplayAddFlag) {
NSLog (#"Display Added");
}
else if (kCGDisplayRemoveFlag) {
NSLog (#"Display Removed");
}
}
#implementation MyClassThatIsInterestedInDisplayConfiguration
- (void) comeOnBabyAndDoTheRegistrationWithMe {
// Register callback function inside a method
CGDisplayRegisterReconfigurationCallback(MyDisplayReconfigurationCallBack,
NULL);
}
#end
*The basic C curly-brace-delimited thing, not the new cool Obj-C ad hoc function thing.