Closed cneuwirt closed 11 years ago
The problem is the iVar layout is hardcoded at compile time while the mixin is applied at runtime.
Have you tried associated objects?
cheers, Florian
Wow, didn't mean to bug you on a Sunday, but thanks. I haven't tried Associative References, but that sounds very interesting and will be taking a look at it.
thanks again, -craig
On Oct 7, 2012, at 10:00 AM, Florian Agsteiner wrote:
The problem is the iVar layout is hardcoded at compile time while the mixin is applied at runtime.
Have you tried associated objects?
cheers, Florian
— Reply to this email directly or view it on GitHub.
No problem, it's actually very easy
-(void)setVariable: (NSString *)myString
{
objc_setAssociatedObject(self, @selector(variable), myString, OBJC_ASSOCIATION_RETAIN);
}
-(NSString *)variable
{
return objc_getAssociatedObject(self, @selector(variable));
}
Indeed, that should work great!!!!
cheers
On Oct 7, 2012, at 10:20 AM, Florian Agsteiner wrote:
No problem, it's actually very easy
-(void)setVariable: (NSString *)myString { objc_setAssociatedObject(self, @selector(variable), myString, OBJC_ASSOCIATION_RETAIN); }
-(NSString *)variable { return objc_getAssociatedObject(self, @selector(variable)); } — Reply to this email directly or view it on GitHub.
Using your mixin support with associated references works perfectly!
can't thank you enough for that this gem. I've been wanting to add a contextual model concepts to cocoa touch to mirror the great support for view and controller hierarchies and this will get me there.
On Oct 7, 2012, at 10:20 AM, Florian Agsteiner wrote:
No problem, it's actually very easy
-(void)setVariable: (NSString *)myString { objc_setAssociatedObject(self, @selector(variable), myString, OBJC_ASSOCIATION_RETAIN); }
-(NSString *)variable { return objc_getAssociatedObject(self, @selector(variable)); } — Reply to this email directly or view it on GitHub.
It's not mine, but i love to use it too ;-)
But i think @vl4dimir will appreciate it :-)
Oops..I'll certainly let him know too.
On Oct 7, 2012, at 10:53 AM, Florian Agsteiner wrote:
It's not mine, but i love to use it too ;-)
But i think @vl4dimir will appreciate it :-)
— Reply to this email directly or view it on GitHub.
Just for my understanding, is there any difference using mixins vs objective c categories?
On Oct 7, 2012, at 10:53 AM, Florian Agsteiner wrote:
It's not mine, but i love to use it too ;-)
But i think @vl4dimir will appreciate it :-)
— Reply to this email directly or view it on GitHub.
They can ca little more:
1) The addition of ivars actually works when the class size is the same po (int)class_getInstanceSize([XYMixin class]) po (int)class_getInstanceSize([XY class])
Thats why -> notation can be difficult
2) I like the following feature, it works by creating a protocol of the host class e.g.
========================
.h
========================
@protocol SimpleClassMethods<NSObject>
- (id) doSomething;
@end
@interface SimpleClassMixin extends NSObject
- (void) convenientMethodThatDoesSomething
@end
========================
.m
========================
@interface SimpleClassMixin <SimpleClassMethods> (CategoryToAvoidWarnings)
@end
@implementation SimpleClassMixin
- (void) convenientMethodThatDoesSomething{
[self doSomething];
}
@end
This allows to add convenient methods without coping them and force the Host Class to implement the protocol
@interface DemoClass extends NSObject<SimpleClassMethods> .....
3) It can be added to more than one class without coping the code to the two categories, actually it is copied but automatically ;-)
4) I would use it to add simiar code to serveral Framework classes, where you don't wont the superclass to have have the code, e.g:
LayoutScrollView extends UIScrollview and LayoutView extends UIview, but i want the code to end up in the Layout* classes not the UIView.
Ah. That makes a lot if sense. Thanks for the explanation.
Sent from my iPhone
On Oct 7, 2012, at 1:48 PM, Florian Agsteiner notifications@github.com wrote:
They can ca little more:
1) The addition of ivars actually works when the class size is the same po (int)class_getInstanceSize([XYMixin class]) po (int)class_getInstanceSize([XY class])
Thats why -> notation can be difficult
I fix it by creating a protocol of the host class e.g.
.h
@protocol SimpleClassMethods
- (id) doSomething; @end
@interface SimpleClassMixin extends NSObject
- (void) convenientMethodThatDoesSomething @end
.m
@interface SimpleClassMixin
(CategoryToAvoidWarnings) @end @implementation SimpleClassMixin
(void) convenientMethodThatDoesSomething{ [self doSomething]; } @end This allows to add convenient methods without coping them and force the Host Class to implement the protocol
@interface DemoClass extends NSObject
..... 2) It can be added to more than one class without coping the code to the two categories, actually it is copied but automatically ;-) — Reply to this email directly or view it on GitHub.
On Oct 7, 2012, at 1:48 PM, Florian Agsteiner wrote:
They can ca little more:
1) The addition of ivars actually works when the class size is the same po (int)class_getInstanceSize([XYMixin class]) po (int)class_getInstanceSize([XY class])'''
How is that possible? Doesn't that suggest adding new ivars to the destination class? Looking at the MixIn code, it only adds methods, so how can it add variables?
Thats why -> notation can be difficult
I fix it by creating a protocol of the host class e.g.
.h
@protocol SimpleClassMethods
- (id) doSomething; @end
@interface SimpleClassMixin extends NSObject
- (void) convenientMethodThatDoesSomething @end
.m
@interface SimpleClassMixin
(CategoryToAvoidWarnings) @end @implementation SimpleClassMixin
(void) convenientMethodThatDoesSomething{ [self doSomething]; } @end This allows to add convenient methods without coping them and force the Host Class to implement the protocol
@interface DemoClass extends NSObject
..... 2) It can be added to more than one class without coping the code to the two categories, actually it is copied but automatically ;-) — Reply to this email directly or view it on GitHub.
I mean copiing the ivars could work sorry.
If you are interested in the subject, here is a reading list:
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html http://blog.mugunthkumar.com/products/introducing-my-book-ios-5-programming-pushing-the-limits/
Great read. Thanks for the links.
The use of obj_setAssociatedObject in my mixin works greats. I did notice that these associations are not always getting cleaned up and most likely leaking. Not sure if its cycles, block usage or something else thats preventing this. It does clean up sometimes.
Thanks again for all your great advice on this subject
cheers
On Oct 9, 2012, at 1:15 PM, Florian Agsteiner wrote:
I mean copiing the ivars could work sorry.
If you are interested in the subject, here is a reading list:
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html http://blog.mugunthkumar.com/products/introducing-my-book-ios-5-programming-pushing-the-limits/
— Reply to this email directly or view it on GitHubhttps://github.com/vl4dimir/ObjectiveMixin/issues/9#issuecomment-9272873.
They are cleaned up when the object is deallocated.
So when you have a delegate make sure to set it to OBJC_ASSOCIATION_ASIGN.
If it is a block, that contains "self" it will result in a retainCycle because the object retains the block and the block the object. To cut the cycle the best way is to use an external lifeCycle event, for example [UIViewController viewDidDisappear] or [UIView didMoveToWindow] and window == nil, etc...
There is a good tool hidden in the instrument leaks to visualize retain cycles!
Cheers, Florian
Turned out there really wasn't a leak after all. I was tricked by my unit tests into believing there was due to the delayed draining of the autoreleasepool by the tests. Introducing a local @autoreleasepool eliminated the leaks.
thanks again -craig
On Oct 10, 2012, at 1:17 PM, Florian Agsteiner wrote:
They are cleaned up when the object is deallocated.
So when you have a delegate make sure to set it to OBJC_ASSOCIATION_ASIGN.
If it is a block, that contains "self" it will result in a retainCycle because the object retains the block and the block the object. To cut the cycle the best way is to use an external lifeCycle event, for example [UIViewController viewDidDisappear] or [UIView didMoveToWindow] and window == nil, etc...
There is a good tool hidden in the instrument leaks to visualize retain cycles!
Cheers, Florian
— Reply to this email directly or view it on GitHub.
I tried mixing into UiViewController or any class that has existing ivars which resulted in mismatched ivars. Since existing instance variables cannot be added after registration, the mixed in ivars will overwrite the corresponding location in the destination class. Is there a test that shows mixing into a source class with ivars into a destination class with ivars? If not I could write a failing one.
cheers, craig