bertrand-caron / bctrackingclass Goto Github PK
View Code? Open in Web Editor NEWObjective-C class setting up method swizzling for tracking message sending
License: MIT License
Objective-C class setting up method swizzling for tracking message sending
License: MIT License
Having a finite, static list of IMP dealing with a given number of arguments :
void myIMP0Args(id self, SEL _cmd);
void myIMP0Args(id self, SEL _cmd)
{
//NSLog(@"_cmd : %@",NSStringFromSelector(_cmd));
[BCTrackingClass logCallForMethod:NSStringFromSelector(_cmd)];
objc_msgSend(self,
NSSelectorFromString([NSString stringWithFormat:@"tracked%@",NSStringFromSelector(_cmd)]));
}
void myIMP1Args(id self, SEL _cmd, id object);
void myIMP1Args(id self, SEL _cmd, id object)
{
//NSLog(@"_cmd : %@",NSStringFromSelector(_cmd));
[BCTrackingClass logCallForMethod:NSStringFromSelector(_cmd)];
objc_msgSend(self,
NSSelectorFromString([NSString stringWithFormat:@"tracked%@",NSStringFromSelector(_cmd)]),
object);
}
and dispatched based on method_getEncoding()
:
if ( //0 Args))
{ class_addMethod(aClass,
trackedSelector,
(IMP) myMethodIMP, "v@:");
}
else if (//1 Args)
{
class_addMethod(aClass,
trackedSelector,
(IMP) myMethodIMP1Arg, "v@:@");
}
//...
``
Supported natively by the swizzling design : swizzling swizzled methods restores the state of the method (and leaves behind a selector, don't thing it matters too much but could look into it later on).
I finally come up with a working version of the code (cf Github repo, or just above). My next problem is : I want my class to be instance based (currently, all my methods are class methods), so that I can assign a property @property NSMutableDictionnary*
to instances of the class for call logging.
I'm not sure how to achieve that. Any ideas ?
Right now, I'm settinp up swizzing by calling [NCTrackingClass setUpTrackingForClass: myClass andMethodArray:anArray];
Since all my methods are class methods, I don't have any memory and have to 'output' everything.
What I would like to do is spawn an instance of a tracker and have it receive the tracking events :
BCTrackingClass* tracker = [[BCTrackingClass alloc] init];
[tracker registerTrackingForClass : myClass andMethodArray:anArray];
Then give an @property NSMutableDictionnary* trackingDict
that would be queried by :
[tracker getTrackingDict];
In my IMP, I want self to be both my BSTrackerClass
instance to be able to send back the message to its owner, and BCTrackingClass
to be able to log information in self
.
void myMethodIMP(id self, SEL _cmd)
{
//NSLog(@"_cmd : %@",NSStringFromSelector(_cmd));
[BCTrackingClass logCallForMethod:NSStringFromSelector(_cmd)];
objc_msgSend(self,
NSSelectorFromString([NSString stringWithFormat:@"tracked%@",NSStringFromSelector(_cmd)]));
}
Using class_addIvar()
, we could imagine adding a @property BCTrackingClass instance
programmatically to classes of objects being tracked, so that we can refer to them in the IMP.
Using a Singleton Pattern :Singleton Pattern on Wikipedia
Now that we are actually able to catch calls to every functions we want to track, what should we do with it ?
Logging them in a NSMutableDictionary
=>
Different class with same methods will have their calls logged together.
@"doA"
: ->@"TrackedClass doA:"
-(void)logCallForMethod:(NSString*)aSelectorString
->-(void)logCallForMethod:(NSString*)aSelectorString andClass:(NSString*)aClass
Given a method doAwesomeFeature
, we can define a duration t
after which the user should be reminded that this feature might help him.
If the method is not used enough, we might define a threshold.
Framework method : [BCTrackedClass trackMethod:aMethod withTrackingMask:trackingMasj]
What about a NSMutableDictionnary
-based approach ?
NSDictionary* trackingMask =
@{
@"trackingType" : [NSNumber numberWithInt:BCUnderusedMethod],
@"reminderTime" : @60, //In s
@"reminderThreshold" : @4
};
A method used too often in a given time is symptomatic os something wrong.
Example :
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.