How to Free a Component in Android/Ios

Freeing dynamically-created controls in Android

Prior to RAD Studio 10.4, Delphi uses ARC (Automatic Reference Counting) for object lifetime management on iOS and Android platforms. Under ARC, TObject.Free() and FreeAndNil() do not behave as you are expecting. They are translated by the compiler into mere nil assignments, decrementing the object's reference count. An object is not freed until its reference count falls to 0.

In your example, the object in question has multiple references (inside the Controls[] list, and in the oControl variable), so the FreeAndNil() does not have the desired effect since it is merely setting the oControl variable to nil and not removing the object from the Controls[] list. In other words, your example is effectively the same as the following:

for i := oParentRect.ControlsCount-1 downto 0 do
begin
oControl := oParentRect.Controls[i]; // <-- increments refcnt
if (oControl is TText) or (oControl is TEdit) then
begin
//FreeAndNil( oControl );
oControl := nil; // <-- decrements refcnt
end;
end;

If you really want to destroy an object immediately when coding under ARC, you need to use TObject.DisposeOf() instead, eg:

for i := oParentRect.ControlsCount-1 downto 0 do
begin
oControl := oParentRect.Controls[i]; // <-- increments refcnt
if (oControl is TText) or (oControl is TEdit) then
begin
//FreeAndNil( oControl );
oControl.DisposeOf; // <-- destroys object, but does not free its memory yet
oControl := nil; // <-- decrements refcnt
end;
end;

Under this model, when an object is "disposed of", its destructor is called immediately, but its underlying memory block is not freed yet. Reference counting still occurs on the block. The object is in a "disposed" state until its reference count falls to 0, then the memory block is freed. The destructor is not called again.

This behavior is documented on Embarcadero's DocWiki:The Free and Dispose Of methods under ARC

Now, that being said, in RAD Studio 10.4, Embarcadero has removed object ARC handling completely, going back to the traditional memory management model (which they now refer to as "Unified Memory Management"). In which case, TObject.Free() and FreeAndNil() now behave the same as they always have on non-mobile platforms, but now on all platforms equally. So your original code will now work as expected, you do not need to switch to TObject.DisposeOf() in 10.4 onwards (though, you can if you want to, it will behave exactly like TObject.Free(), and give you the desired effect if you need to support 10.3 and earlier).

What's the correct way to develop components for Android and iOS?

There is a very simple solution which I prefer. Just use the file extension: .ios. vs .android.

Sample Image

E.g. look at my nav. I use the android toolbar in the android nav and then I can use navigatorIos for ios if I wish. The application platform will correctly load the corresponding platform file just based on the extension. Which means I just load it normally:

var Nav = require('./jsx/Nav');

I like to follow a declarative approach that React talks about, thus:

1) organizing your files would be by function/behaviour and not by platform as the same file with different extensions will be next to each other.

2) Whether platform to be explicit or implicit isn't relevant as you will only split the file into extensions when it's different platform specific components (so this is inherent)

3) Never any need to handle different platform(s) behaviour in your code ever.

4) This is a composition solution as I've already mentioned: files that are cross-platform do not need the platform extension (and might not need an abstract class for extension in some cases even).

This is a simple solution and I do not know how well it would scale for large projects; but I'm all for the declarative simplicity about it.

Android/iOS: How to create a web-app, using native componentes?

You can make a cross-platform app using framework like phoneGap for example.

With his java script methods you can use the device native components.

This is a tutorial for that.

Hope that helps

How to do event handling for android and iOS in react native's new architecture for fabric components?

iOS

Assuming native spec you posted is correct (I'm not really familiar with TypeScript + Codegen duo) when you run pod install command in your ios/ directory codegen should generate EventEmitters cpp file (+ header) in React-Codegen pod (you can see below how to find it in XCode)

link to the screenshot with Pods structure

You can then use these classes in your Objective-C++ code to emit the events:

if (_eventEmitter != nullptr) {
std::dynamic_pointer_cast<const facebook::react::$$NAME OF YOUR EVENT EMITTER TYPE$$>(_eventEmitter)
->onEvent(facebook::react::$$NAME OF YOUR EVENT EMITTER TYPE::OnEvent{.value = $$VALUE$$});
}

See links below to see how it is done in react-native-screens

  1. Native component spec in Flow
  2. Event emission in Obj-C++ code
  3. Event exposure in screen manager - I'm not quite sure if this line is necessary, haven't tested it out yet.

Android

  1. To trigger codegen just run native build.
  2. Define native event class as done here
  3. Take a look here for how to dispatch event
  4. Export your event types

iOS and Android programming

Is there any method by which I can focus on developing my iOS
application in such a way that I can reuse some of its components or
features for developing the same application on the Android platform?

You can if you use web technologies (HTML, CSS, Javascript). You can do that if you build a web-based app or a hybrid app, i.e. one that uses web-based content running inside a native shell. Look into PhoneGap if you're interested in building a hybrid app -- it offers a quick way to get started. There are also some cross-platform frameworks like Titanium that purport to offer write once/run on several platforms functionality.

If you want to build an app that's fully native on both platforms, you won't be able to reuse application logic. iOS and Android use different frameworks written in different languages running on different hardware, and apps on each platform work somewhat differently as well. Even so, what you can re-use is whatever work you put into the infrastructure that drives the apps. Most apps rely on some sort of server infrastructure to supply or collect data, and that server component can easily serve apps running on either platform.

How to properly use iOS only components in React Native without error in Android

What I would suggest is splitting that platform specific code in separate files.

React Native will detect when a file has a .ios. or .android.
extension and load the relevant platform file when required from other
components.

MyFile.ios.js
MyFile.android.js

You can then require the component as follows:

const MyFile= require('./MyFile');

and use it like this

componentWillMount: function() {
//-- it would call the logic of what ever platform was detected automatically
MyFile.CallWhatEver();

And it will run the platform specific code.

Another way is the

Platform Module

React Native provides a module that detects the platform in which the
app is running. You can use the detection logic to implement
platform-specific code. Use this option when only small parts of a
component are platform-specific.

if(Platform.OS === 'ios')

There is also a platform.select that can accept any value

const Component = Platform.select({
ios: () => //function goes here,
android: () => require('ComponentAndroid'),
})();

link
https://facebook.github.io/react-native/docs/platform-specific-code.html



Related Topics



Leave a reply



Submit