I did ATL programming many years ago and now going down that path again. I remember last time, there was a way for the compiler to optimize put_ and get_ (that is properties) automatically. I really cannot find out how I did it last time.
Currently I am doing this:
// assume p is a pointer to an interface
CComBSTR name;
p->get_Name(&name);
This code is really bugging me, and I am sure there is a better way:
// can we do this?
CComBSTR name(p->get_Name());
// or maybe this
CComBSTR name(p->Name);
I could not figure out how to do this using CComPtr and _com_ptr_t. Also note that p is a pointer to an interface in the same library. So I am not using #import or anything.
CComBSTR name(p->Name); is the right thing
Related
If I put an NSURL in a class declaration and set it to something in a method, when the method finishes the object it's pointing to is gone. Is there a way to have a non pointer version of an object in the declaration like you can in C++? XCode doesn't seem to want to let me.
Is there a way to have a non pointer version of an object in the declaration like you can in C++? XCode doesn't seem to want to let me.
NSObject types don't support this. Even creating your own root objc class is not supported with Clang (you could do it with GCC if you were geeky enough). Thus, the short answer is "No, you can't declare a NSObject type by value".
But that's not really important; the right solution is to figure out why your member is cleared -- using ref counted pointers works for everybody else.
Not knowing Obj-C I could use some help to traslate this one line of code:
[[TVOutManager sharedInstance] startTVOut];
into a C# version I can use in MonoTouch.
I've managed to get the XCode project compiled to a static library, now I'm trying to figure out how to turn it on... The orginal project is posted here: http://www.touchcentric.com/blog/
TIA,
Rick
[obj myMsg] is Objective-C syntax for sending the myMsg message to the obj instance. It is, at first blush, a lot like obj.myMsg() in C#. Objective-C uses message passing rather than function calls, however, so the two are actually very different semantically. You can often gloss over the differences, but if you are going to do any significant work on OS X or iOS, it's worth reading the Objective-C language guide carefully. I'm not a MonoTouch/MonoMac expert, but I believe that the answer to your specific question is:
TVOutManager.sharedInstance.startTVOut();
assuming sharedInstance is mapped as a static property of type TVOutManager, or
TVOutManager.sharedInstance().startTVOut();
if sharedInstance is mapped as a class method in Objective-C.
This isn’t the original code (I stripped things back in trying to simplify for debugging), but it does display the problem. On the face of it, looks simple enough:
- (void) testMethod: (TouchData) toi {
TouchData newToi = toi;
NSString *test = #"test string";
NSLog(#"string: %#", test);
// in ‘real’ code I pass the struct back
// It’s void here for the simplest possible
// case
}
TouchData is a struct, declared thus:
typedef struct {
Entity *owner;
CGPoint startPos;
CGPoint latestPos;
CGPoint startOfStraightSwipePos;
NSTimeInterval startTime;
NSTimeInterval latestTime;
NSTimeInterval startOfStraightSwipeTime;
CGFloat latestSpeed;
NSMutableArray *gestures;
BOOL isOfInterest;
} TouchData;
When I step through testMethod in the debugger (watching toi) on hitting NSLog (which doesn't even involve toi), all toi member values suddenly zero out. This doesn’t happen to the copy (newToi). It doesn’t happen if I pass the struct in by reference. It doesn’t happen if replace the testMethod invocation directly with the method body (ie. if I run these lines in situ rather than calling into a method). It doesn’t happen if I change the toi parameter type to a dummy struct with a couple of int members, created just before the call.
It might worth pointing out that testMethod is only called from within its own
class, and that the caller has just extracted the struct from an NSMutableDictionary (via unboxing an NSValue). But given that (a) the struct is
passed into the method here by value, and (b) that on entry its members as shown
by the debugger are all as expected, I don’t see that this can be causing a problem. There is also the thorny issue of the two object pointers in the struct, but in other contexts they’re working out OK, and they check out in the debugger on entry to the method, so I don’t think I’ve missed essential retains.
I presume I’m running into some kind of heap or stack corruption, but I’ve no idea how or why. I’m new to Objective-C, and have previously worked in
garbage collected environments, so my memory management experience is limited. It’s entirely possible that I’ve missed something painfully obvious.
I expect someone will tell me to make TouchData an object type instead, and indeed I may well go that way. I also have a couple of tested workarounds, ie. to either work on a copy, or pass the struct in by ref. But I’d really like to know what’s going on here.
If toi is not used after the line TouchData newToi=toi, the compiler can do whatever it wants to do in the stack memory where toi originally was placed after that line. For example, it might reuse the stack memory when calling another function, in this case NSLog.
So, watching toi by a debugger might show something strange. The compiler does often do these things, in particular if the optimization is turned on. Even with no optimization there's no guarantee that the stack location of toi is left intact after it's last used.
By the way, you said having object pointers inside toi didn't cause problems, but it's a tricky situation and I recommend strongly against that practice. Follow the standard retain/release rules; otherwise, another programmer who takes a look at your code (who might be yourself two years from now) would be totally confused. Also, the static analyzer (which can be accessed by doing Build & Analyze in XCode) might be confused and might give false positives. So, don't do that.
I've never worked with a language that didn't provide for some form of memory management, and thus managed to get by without ever really groking pointers.
I can dabble in C I guess, as a result of coding in Objective-C for a little while.
Hmmm, maybe it's the single linked list.
Try it: create, populate, reverse, release a single linked list
struct node {
int data;
struct node *next;
};
I wouldn't call this "canonical", but I'm recreating [arrayOfStrings sortUsingSelector:#selector(compare:)]; using char * arrays and pure C code. It's sloppy and frustrating, but great practice and I'm loving it.
http://github.com/jkubicek/Objective-Sort/blob/master/Objective-Sort.m
I've started a small github project to collect objective-c katas: https://github.com/twobitlabs/xcode-katas
Can I, in the GNU Objective-C runtime, attach semi-arbitrary pieces of data to instance variables?
Challenge:
I'm currently working on a kind of Cocoa workalike for Linux, as a sort of pet project. (Please, let's not get sidetracked by all the "use GNUStep" stuff. I know about it, but it doesn't suit my needs. Moving on…) For this purpose I'm trying to cobble together a simple ORM system, reminiscent of DBIx::Class for Perl. The general idea is to make the declaration as simple (read: short) as possible, and if at all possible, without the need to provide +(id)constantClassAttribute methods for overriding.
The general idea is to declare my result classes as follows:
#interface SomeTable : ORMResult {
unsigned long long id;
ORMResult *toOneRelation;
ORMResultSet *toManyRelation;
}
#end
So far, so hoopy. I can now access these fields using [ORMResult self]->ivars, and do all manner of nasty stuff, like automagically generating accessors like -[toManyRelation] or -[setToOneRelation]. Piece of cake. Unfortunately, there are two pieces of information I cannot add using this setup; one is simple enough to solve, the other not so much:
What is the actual result class?
This is solved by subclassing ORMResult (like SomeTable), and plugging that in
there, using runtime dynam(ag)ics to figure out it's to-ness (toMany, toOne).
(And this is the tricky one!) Is the relationship nullable?
This is less easily solved. My initial ideas were
(ab)using protocols, like so:
#interface SomeTable : ORMResult {
unsigned long long id;
ORMResult <ORMNullable> *toOneRelation;
}
#end
This compiles, but unfortunately, when I try to use GDB to inspect the
ivars->ivar_list entries I find that the protocol information isn't actually kept
for the runtime to toy with. This makes, I suppose, some kind of twisted sense,
as protocol declarations are mostly for the compiler.
Abusing the protocol identifiers (byref, bycopy and friends, using defines:
#interface SomeTable : ORMResult {
unsigned long long id;
nullable OMRResult *toOneRelation;
}
#end
This has the rather obvious drawback of not actually working, as these
specifiers apparently only work in protocol method declarations.
The question, then, is how can this attachment of information to the ivars be pulled off in practice?
Note: As mentioned initially, I'm using the GNU Objective-C runtime, as supplied by GCC on Linux; and not the one supplied by Apple!
Edit: Starpox! I forgot a central point: An alternative, of course, is to simply make all relations nullable. This I don't really want, but if no other alternative exists, I guess that's the path I'll end up going down.
Well, how we used to do this in ye olde days on the Mac was to create a global variable holding an NSMutableDictionary into which we put the data we want to attach to an object. Simply use a string representation of the pointer as the key.
The only difficulty becomes figuring out when an object has gone away and making sure that its entry in the dictionary is removed as well. You may have to resort to hackery like method swizzling -dealloc to achieve that.
You might look at objc_setAssociatedObject and friends, which allow you to attach arbitrary data to an object. However, I'm not sure if they're supported in the version of libobjc that you're running.