Thread: [Pyobjc-dev] class vs. instance attributes for IBOutlets
Brought to you by:
ronaldoussoren
From: Joe S. <jo...@st...> - 2008-10-12 14:12:35
|
I'm re-learning Python, and learning Cocoa and PyObjC all at the same time. So maybe this is silly question: The examples I've seen have the IBOutlets (and often data too) defined at the class level, like so: class ToDoListAppDelegate(NSObject): toDoTableView = objc.IBOutlet() newItemField = objc.IBOutlet() toDoList = [] But it occurred to me last night that this would be a problem in an NSObject class that might have more than one instance -- wouldn't apply to the app delegate, of course, but it could apply to a window controller. So I moved the toDoList (which is a mutable type) to the init function. Then, on a lark, I found I could move the IBOutlets there too, so it looks like this: class ToDoListAppDelegate(NSObject): def init(self): NSLog(u"init") self.toDoTableView = objc.IBOutlet() self.newItemField = objc.IBOutlet() self = super(ToDoListAppDelegate, self).init() if self is not None: self.toDoList = [] return self So here's my question: is this necessary for IBOutlets (in a non- singleton class of course)? Or is it not necessary, perhaps because this is an immutable type? And what's the standard best practice for these things? Thanks, - Joe |
From: Will L. <le...@gm...> - 2008-10-12 15:17:27
|
Joe, In order to access the class variable, you'd need to be accessing ClassNa property me.instead of 'self.property'. I this this brief console session help clarify the difference: >>> class Person(object): ... name = "Tim" ... age = 25 ... >>> x = Person() >>> x <__main__.Person object at 0x80870> >>> x.name 'Tim' >>> x.name = "Will" >>> x <__main__.Person object at 0x80870> >>> x.name 'Will' >>> Person.name 'Tim' ``x`` starts out with the class instance for ``name``, but once you attempt to modify it via ``x.name`` it masks the class property with an instance property. This means that you can safely create multiple instances of one class that appear to modify class variables without causing any trouble. (To actually modify the class property, you'd need to do ``Person.x = 'Jack'``.) I'm curious if InterfaceBuilder can actually detect IBOutlets which are initialized inside the __init__ method (not sure), if not, that might explain why we've adopted a slightly less Pythonic approach. Personally, I'd continue declaring properties as class properties until you run into a situation where doing so is strongly undesirable. In the long run, it's mostly a stylistic element. -Will On Oct 12, 2008, at 10:12 AM, Joe Strout wrote: > I'm re-learning Python, and learning Cocoa and PyObjC all at the same > time. So maybe this is silly question: > > The examples I've seen have the IBOutlets (and often data too) defined > at the class level, like so: > > class ToDoListAppDelegate(NSObject): > toDoTableView = objc.IBOutlet() > newItemField = objc.IBOutlet() > toDoList = [] > > > But it occurred to me last night that this would be a problem in an > NSObject class that might have more than one instance -- wouldn't > apply to the app delegate, of course, but it could apply to a window > controller. So I moved the toDoList (which is a mutable type) to the > init function. Then, on a lark, I found I could move the IBOutlets > there too, so it looks like this: > > class ToDoListAppDelegate(NSObject): > def init(self): > NSLog(u"init") > self.toDoTableView = objc.IBOutlet() > self.newItemField = objc.IBOutlet() > self = super(ToDoListAppDelegate, self).init() > if self is not None: self.toDoList = [] > return self > > So here's my question: is this necessary for IBOutlets (in a non- > singleton class of course)? Or is it not necessary, perhaps because > this is an immutable type? And what's the standard best practice for > these things? > > Thanks, > - Joe > > > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's > challenge > Build the coolest Linux based applications with Moblin SDK & win > great prizes > Grand prize is a trip for two to an Open Source event anywhere in > the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev |
From: Joe S. <jo...@st...> - 2008-10-12 23:14:11
|
On Oct 12, 2008, at 9:17 AM, Will Larson wrote: > ``x`` starts out with the class instance for ``name``, but once you > attempt to modify it via ``x.name`` it masks the class property with > an instance property. This means that you can safely create multiple > instances of one class that appear to modify class variables without > causing any trouble. (To actually modify the class property, you'd > need to do ``Person.x = 'Jack'``.) This is only true for immutable properties. Try this: >>> class Foo: ... list = [] ... >>> a = Foo() >>> b = Foo() >>> a.list [] >>> a.list.append(1) >>> a.list [1] >>> b.list [1] And of course a.list.append is exactly what I was doing with 'toDoList' in my real app. But whether this applies to IBOutlets, I have no idea -- I don't understand what they are or how they work. This was my question. > I'm curious if InterfaceBuilder can actually detect IBOutlets which > are initialized inside the __init__ method (not sure), if not, that > might explain why we've adopted a slightly less Pythonic approach. My experimentation shows that it does not, but it DOES detect them if they're set up in the init() method as I showed on my last email. Best, - Joe -- Joe Strout jo...@st... The candidates answer the top 14 science questions facing America: http://www.sciencedebate2008.com/www/index.php?id=40 |
From: Greg E. <gre...@ca...> - 2008-10-13 02:13:49
|
Joe Strout wrote: > But whether this applies to IBOutlets, I > have no idea -- I don't understand what they are or how they work. I think the IBOutlet is just a marker indicating that the attribute in question is an outlet, and it doesn't hold any state -- in which case sharing it between instances is fine. -- Greg |
From: Ronald O. <ron...@ma...> - 2009-02-03 12:56:30
Attachments:
smime.p7s
|
On 13 Oct, 2008, at 4:13, Greg Ewing wrote: > Joe Strout wrote: > >> But whether this applies to IBOutlets, I >> have no idea -- I don't understand what they are or how they work. > > I think the IBOutlet is just a marker indicating > that the attribute in question is an outlet, and > it doesn't hold any state -- in which case sharing > it between instances is fine. I haven't read pyobjc-dev for a while (for various reasons). objc.IBOutlet and objc.ivar define fields in the Objective-C class and *must* be used at the class level. They basicly claim space in the memory layout of the ObjC instances and are somewhat comparible to the __slots__ attribute in pure Python classes. That is: class MyClass (NSObject): foo = objc.IBOutlet() bar = objc.ivar() This code results in an ObjC class that has two instance variables, "foo" and "bar", that can contain references to arbitrary object. The objc.IBOutlet is intented to be used from Interface builder and will automaticly show up in IB when you create an instance of the class there. Ronald > > > -- > Greg > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's > challenge > Build the coolest Linux based applications with Moblin SDK & win > great prizes > Grand prize is a trip for two to an Open Source event anywhere in > the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev |