I am curious about when the class side initialize messages are sent in Smalltalk (Pharo and Squeak particularly). Is there any specified order? Is it at least safe to assume all other classes packaged with it have already been loaded and compiled, or does the system eagerly initialize (send initialize before even finishing loading and compiling the other classes)?
The class-side initialize is never sent by the system. During development you do it manually (which is why many of these methods have a "self initialize" comment.
When exporting code of a class into a changeset, the exporter puts a send of initialize at the very end, so it gets executed when the class is loaded into another system.
This behavior is mimicked by Monticello. When loading a class for the first time, or when the code of the initialize method was changed, it is executed. That is because conceptually MC builds a changeset on-the-fly containing the difference of what is in the image already and what the package to be loaded contains. If that diff includes a class-side initialize method, it will be executed when loading that package version.
As you asked about loading and compiling, I'm assuming you mean when loading code...
When loading a package or changeset, class-side #initialize methods are called after all code is installed (1). While you can not count on a specific order, you can assume that all classes and methods from that package are loaded.
As Bert pointed out, if you were not loading but implementing class-side #initialize, you'd have to send the message yourself.
One way to know for sure, is to test it yourself. Smalltalk systems make this kind of thing a little more approachable than many other systems. Just define a your own MyTestClass, and then implement your own class side (that's important) initialize message so that you can discover for yourself when it fires, how often it fires, etc.
initialize
Transcript show: 'i have been INITIALIZED!!! Muwahahahah!!!'
Make sure it works by opening a Transcript and running
MyTestClass initialize
from a Workspace. Now you can play with filing it out and back in, Monticello loading, whatever and when it runs.
Related
In a rails app using sorbet, when you have a method that expects an instance of a type, say Foo. And you need to initialize an instance of Foo in an initializer for the app that persists in memory between requests. And then you make any change to the source code of Foo or any file that Foo uses. Then sorbet believes that this instance is no longer an instance of Foo, and you need to restart your app in order for it to stop erroring.
This seems like a rare case, but in our app, we use a bit of dependency injection, and it's a large team. So sorbet is making us restart our app almost every time we do a git update, and many, many times throughout the day as we write code. We have a large app which takes a while to restart, and it's quite frustrating to have to do this.
Any ideas on how to fix this? If helpful, I could make a sample rails app to demonstrate this behavior.
I ran into a similar issue myself when I was referencing a model in a Rails initializer. I was advised that there are 2 solutions:
Refactor the code so that you don't have this issue
Add checked(:tests) or checked(:never) to the sigs of methods that are having this problem. This would preserve the runtime and test time checks, but eliminate the errors in development. See the link below for documentation
https://sorbet.org/docs/runtime#checked-whether-to-check-in-the-first-place
Say I dynamically load a framework via dlopen(), or load a bundle via [NSbundle load] that have a class with the same name as one already in the runtime. What happens to the runtime? What class definition wins?
Probably, the second will win. However, it's almost certainly an implementation detail that is subject to change at Apple's whim.
This is explicitly undefined behavior. In fact, if you load a bundle via the NSBundle API, it will actually give an error message that says it detected the conflict, and the behavior is undefined as to how it handles the conflict.
The basic rule is to not do that. ;-)
I'm working on Phratch (Scratch 2.0 in Smalltalk) and have modified the InputEventSensor>>processEvent method to store the last key pressed, in a similar manner to how the modifier keys are stored, so that they if <key> pressed blocks work.
So I now have a customised InputEventSensor class:
new instance variable keyPressed
modified method processEvent
new methods keyPressed and clearKeystate
The new methods are in a category *Phratch which is fine, so these get saved to the Phratch Monticello package. But what about processEvent, should that be moved to the *Phratch category? What about the instance variable?
There are several things going on :).
First, moving an existing method to your project's package is what we call an override. That is, when you load your package into the image, the existing method definition will be overriden by your definition. I wouldnt advice to make overrides only when extremely necessary. Actually, the best approach should be to create hooks, integrate them in Pharo's codebase, and then plug your project in the given hook :).
On extending classes with instance variables, I don't think Monticello handles that really. A possible solution is to add a pre-load action in a metacello configuration, adding the instance variable to the given class. That way, the inst var is installed before the methods.
Third and last, the actual good way to know if some key is still pressed, is to listen to the KeyDown and KeyUp events. A key is released when a KeyUp event is given. However, keyDown and keyUp events are not properly working on Pharo right now (in all platforms, the keycodes to identify the keys yield OS specific values, and there are some keys that are not well handled yet). But, I'm confident this will get better in the upcoming 3.0 version of Pharo.
Of course, you can contribute if you want to make any of this points better :).
I want to create a simple to use and lightweight performance profile framework for Objective C. My goal is to measure the bottlenecks of my application.
Just to mention that I am not a beginner and I am aware of Instruments/Time Profiler. This is not what I am looking for. Time Profiler is a great tool but is too developer oriented. I want a framework that can collect performance data from a QA or pre production users and even incorporate in a real production environment to gather the real data.
The main part of this framework is the ability to measure how much time was spent in Objective C message (I am going to profile only Objective C messages).
The easiest way is to start timer in the beginning of a message and stop it at the end. It is the simplest way but its disadvantage is that it is to tedious and error prone - if any message has more than 1 return path then it will require to add the "stop timer" code before each return.
I am thinking of using method swizzling (just to note that I am aware that Apple are not happy with method swizzling but these profiled builds will be used internally only - will not be uploaded on the App Store).
My idea is to mark each message I want to profile and to generate automatically code for the method swizzling method (maybe using macros). When started, the application will swizzle the original selector with the generated one. The generated one will just start a timer, will call the original method and then will stop the timer. So in general the swizzled method will be just a wrapper of the original one.
One of the problems of the above idea is that I cannot think of an easy way how to automatically generate the methods to use for swizzling.
So I greatly will appreciate if anyone has any ideas how to automate the whole process. The perfect scenario is just to write one line of code anywhere mentioning the class and the selector I want to profile and the rest to be generated automatically.
Also will be very thankful if you have any other idea (beside method swizzling) of how to measure the performance.
I came up with a solution that works for me pretty well. First just to clarify that I was unable to find out an easy (and performance fast) way to automatically generate the appropriate swizzled methods for arbitrary selectors (i.e. with arbitrary arguments and return value) using only the selector name. So I had to add the arguments types and the return value for each selector, not only the selector name. In reality it should be relatively easy to create a small tool that would be able to parse all source files and detect automatically what are the arguments types and the returned value of the selector which we want to profile (and prepare the swizzled methods) but right now I don't need such an automated solution.
So right now my solution includes the above ideas for method swizzling, some C++ code and macros to automate and minimize some coding.
First here is the simple C++ class that measures time
class PerfTimer
{
public:
PerfTimer(PerfProfiledDataCounter* perfProfiledDataCounter);
~PerfTimer();
private:
uint64_t _startTime;
PerfProfiledDataCounter* _perfProfiledDataCounter;
};
I am using C++ to use that the destructor will be executed when object has exited the current scope. The idea is to create PerfTimer in the beginning of each swizzled method and it will take care of measuring the elapsed time for this method
The PerfProfiledDataCounter is a simple struct that counts the number of execution and the whole elapsed time (so it may find out what is the average time spent).
Also I am creating for each class I'd like profile, a category named "__Performance_Profiler_Category" and to conforms to "__Performance_Profiler_Marker" protocol. For easier creating I am using some macros that automatically create such categories. Also I have a set of macros that take selector name, return type and arguments type and create selectors for each selector name.
For all of the above tasks, I've created a set of macros to help me. Also I have a single file with .mm extension to register all classes and all selectors I'd like to profile. On app start, I am using the runtime to retrieve all classes that conforms to "__Performance_Profiler_Marker" protocol (i.e. the registered ones) and search for selectors that are marked for profiling (these selectors starts with predefined prefix). Note that this .mm file is the only file that needs .mm extension and there is no need to change file extension for each class I want to profile.
Afterwards the code swizzles the original selectors with the profiled ones. In each profiled one, I just create PerfTimer and call the swizzled method.
In brief that is my idea which turned out to work pretty smoothly.
My XCode project has grown somewhat, and I know that there are class files in there which are no longer being used. Is there an easy way to find all of these and remove them?
If the class files just sit in your project without being part of a target, just click on the project itself in the tree view, so you see all files in the table. Make sure you see the "Target" column in the table view, iterate through your targets and find the files that don't have a check anywhere -> they are no longer compiled.
But if you still compile the classes and they are no longer used, that case is a bit more difficult. Check out this project
http://www.karppinen.fi/analysistool/#dependency-graphs
You could create a dependency graph and try to find orphaned classes that way.
Edit: Link went dead, but there still seem to be projects of Objective-C dependency graphs around, for example https://github.com/nst/objc_dep
if they are C or C++ symbols, then you can just let the linker do the work for you.
if you're looking to remove objc symbols, then try to refactor the class name (e.g. to rename the class), and preview the dependencies that it turns up. if you reference classes/selectors/etc. by strings then... it may not be so effective. unfortunately, you often have to also test manually, to verify that removing a class does not break anything. remember that resources (like xibs) may reference/load objc classes as well.
This is a tricky question due to how dynamic objective-c is as you can never guarantee that a class is not going to be used.
Consider if you generate a class name and a selector at run time and then look up that class, instantiate that class and then call a method on that newly created object using that newly created selector. No where in your code do you explicitly name and instantiate that object but you are able to use it anyways. You could get that class name and selector name from anywhere outside of your code, even from some data from a server some where. How would you ever know which class is not going to be used? Because of this there are no tools that are able to perform what you are requesting.
Searching the project with the class name might be an option, thought it may not be the best solution. Specially it might be time consuming when you have many classes.