Comments (10)
Well, something has definitely written to the wrong place in memory :)
Are you calling any C functions via ctypes
directly (not via rubicon.objc
)? If so, this could be a result of an incorrect or missing restype
/argtypes
function signature (although normally that messes up the stack and quickly crashes).
Is the code you're running avaliable somewhere? If not, can you try to come up with a short example that triggers this behavior?
from rubicon-objc.
Now that you mention it, it turns out I do use ctypes
but only as a helper for NSLog
.
Code is at https://github.com/dimaqq/playing-with-python-on-ios/blob/master/app_packages/nslog.py and it's mostly copied from elsewhere on github.
Yes, entire project is available, clone https://github.com/dimaqq/playing-with-python-on-ios open *.xcodeproj
build run.
Then trigger an exception, e.g. by making a typo in https://github.com/dimaqq/playing-with-python-on-ios/blob/master/app_packages/ui/__main__.py#L86 addSubview_ --> addSubView_
from rubicon-objc.
This makes me wonder... what are the rules for following:
- ObjC object that has references in both ObjC and Python world?
- Python object that has references in both worlds?
When do they get garbage-collected?
from rubicon-objc.
@dimaqq rubicon-objc does not affect Objective-C reference counting automatically, you need to call retain
and release
like you would in normal Objective-C code (without garbage collection or ARC).
There is however a special handler (called DeallocationObserver
), which is attached to any Objective-C object wrapped in an ObjCInstance
, which notifies rubicon-objc when an object is freed on the Objective-C side, and disables the corresponding ObjCInstance
. So you should not be able to crash by calling methods on a "dead" ObjCInstance
.
Python objects aren't exposed to the Objective-C world in any special way. ObjCInstance
s are unwrapped of course, and some basic data types are converted to primitives or objects, but you can't pass arbitrary Python objects to Objective-C. If you get a PyObject *
for a Python object, that is not treated specially in any way.
from rubicon-objc.
Oh, I think I know what's happening. NSLog
's first argument is a format string, which means sequences like %s
are substituted with whatever you pass as extra arguments. Your NSLog
Python function passes the Python string unmodified as the first argument, which means that if the Python string contains any formatting specifiers, NSLog
replaces them with random junk from the stack (since you passed no extra arguments).
To prevent this, you can always pass "%s"
as the format string, and the Python string as the only extra argument to NSLog
. (Both need to be wrapped in a NSString
of course.) Then NSLog
will insert the string without replacing any formatting specifiers.
from rubicon-objc.
I'll give it a go on Monday.
from rubicon-objc.
Any news about this @dimaqq? Also I just noticed a mistake in my suggested fix - I think you need to use %@
in the format string instead of %s
, because you're inserting a NSString
and not a C char *
.
from rubicon-objc.
Yes you were right. extension.NSLog(NSString.from_python("%@"), NSString.from_python(s))
is the correct call spec.
And now binary rubbish is gone:
Traceback (most recent call last):
File "rubicon/objc/objc.py", line 1313, in __getattr__
return self.__dict__[name]
KeyError: 'addSubView_'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "ui/__main__.py", line 87, in application_didFinishLaunchingWithOptions_
UIApplication.sharedApplication().keyWindow.addSubView_(view)
File "rubicon/objc/objc.py", line 1316, in __getattr__
raise AttributeError('ObjCInstance %s has no attribute %s' % (self.__dict__['objc_class'].name, name))
AttributeError: ObjCInstance UIWindow has no attribute addSubView_
Real issue solved :)
Obv., "during handling another exc..." is still confusing, but that's always so.
Perhaps raise AttributeError(...) from None
would be better?
There are pros and cons, obv., like Python version dependency.
from rubicon-objc.
OK, good to hear it's working.
IMHO suppressing the chained exception is not a good idea - the current behavior (chained exception is displayed) is standard Python 3 behavior, and seeing the original exception can be useful when debugging the custom __getattr__
method.
from rubicon-objc.
Closing this - the original issue has been solved, and the chained KeyError
was already removed in 1f56856.
from rubicon-objc.
Related Issues (20)
- I am passing the correct number of arguments, however stilling hitting "takes 7 arguments, but got 5 arguments" HOT 5
- Improve repr() calls for NSPoint/NSRect types
- Calling performSelector for a @objc_method created by rubicon from Objective C crashes in Python 3.9 HOT 3
- Blocks not fully working on M1 hardware HOT 5
- "ObjC Class 'b'WrappedPyObject'' couldn't be found." when running on iOS device HOT 7
- iOS event loop blocks when thread waits on socket.
- x86_64 machine architecture not identified correctly on iOS simulator
- Attribute intermittently returns the wrong object HOT 5
- Segmentation fault when exiting multi-threaded program
- Race condition when instantiating ObjCInstance objects
- Race condition when populating the ObjCClass method/attribute cache
- Update CI configuration to test release artefacts
- Improve correspondence between ObjectiveC objects and Python wrappers HOT 17
- New caching logic may inadvertently release objects that are still needed HOT 5
- ctypes.ArgumentError message is split into individual characters
- Warning about deprecated `pkg_resources` API
- Incompatibility with `from __future__ import annotations` HOT 1
- Incompatibility with Python 3.12.0b1 HOT 4
- Scroll blocks eventloop for ios HOT 3
- Can't invoke Protocol methods that collide with object properties HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rubicon-objc.