Re: Why so many public properties all up in my grizzle?

2012-03-23 Thread Sebastian Celis
On Thu, Mar 22, 2012 at 6:39 PM, G S  wrote:
> On Mon, Mar 19, 2012 at 1:35 PM, Sebastian Celis
> wrote:
>
>> 1) Embrace @properties...Exposing _ivars in header files is
>> gross. You never want people to access them directly, so don't make
>> those declarations public at all.
>>
>
>> 2) Technically, nothing is truly private in Objective-C, so let's stop
>> trying to completely prevent people from using private APIs.
>
> contradiction++

I think you misunderstood.

My point on (1) was that directly referencing ivars of other classes
with the -> operator is generally frowned upon in Objective-C. For
one, you miss out on KVO that way. It is generally much more accepted
to use real Objective-C methods and properties. Because of this,
putting ivars in a *public* header file is strange and just clutters
up what could otherwise be a clean, compact public interface
declaration.

My point on (2) was to just try and steer the conversation away from
where it had been headed, which was an expansive discussion on how
Objective-C handles public / protected / private methods and
properties. Yes, private methods aren't really private. I can always
use NSInvocation to call your private methods if I really want to.
What I think is much more interesting is finding the best way to
create compact, readable public header files that API consumers can
reference while still finding good ways to use both traditionally
private and protected methods in your class and subclasses. I just
want to keep those out of the public header file — not to *prevent*
you from using them, but just to communicate to you that you should
try to avoid them.

- Sebastian

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-22 Thread T.J. Usiyan
Well damn, @package accomplishes the 'compilation unit' request.
On Thu, Mar 22, 2012 at 8:36 PM, T.J. Usiyan  wrote:

>
>> > 2) Technically, nothing is truly private in Objective-C, so let's stop
>> > trying to completely prevent people from using private APIs.
>>
>>
>> contradiction++
>> ___
>>
>>
> Not quite. You actually CAN hide the ivars and it is odd to expose them
> because you have the ability to hide them. Exposing the accessor method
> INSTEAD of the ivar is usually better. I know that it is not always
> convenient and hope that we eventually get the ability to access self's
> ivars if we are in the same compilation unit, but until then, exposing
> accessors seems like a better option.
>
> TJ
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-22 Thread T.J. Usiyan
>
>
> > 2) Technically, nothing is truly private in Objective-C, so let's stop
> > trying to completely prevent people from using private APIs.
>
>
> contradiction++
> ___
>
>
Not quite. You actually CAN hide the ivars and it is odd to expose them
because you have the ability to hide them. Exposing the accessor method
INSTEAD of the ivar is usually better. I know that it is not always
convenient and hope that we eventually get the ability to access self's
ivars if we are in the same compilation unit, but until then, exposing
accessors seems like a better option.

TJ
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-22 Thread G S
On Mon, Mar 19, 2012 at 1:35 PM, Sebastian Celis
wrote:

> 1) Embrace @properties...Exposing _ivars in header files is
> gross. You never want people to access them directly, so don't make
> those declarations public at all.
>


> 2) Technically, nothing is truly private in Objective-C, so let's stop
> trying to completely prevent people from using private APIs.


contradiction++
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-21 Thread Sebastian Celis
On Mon, Mar 19, 2012 at 2:27 PM, Brian Lambert wrote:
> Is there a way to declare ivars in the .M file AND have them accessible
> from Objective-C Category files for the class?

I will tell you how we handle public, private, and protected ivars and
properties. The route we decided to take was influenced by a number of
overall design goals:

1) Embrace @properties. Properties are great. They make memory
management easier, they work with ARC, and they force us to document
our code and think about relationships between objects (weak vs
strong, atomic vs nonatomic). Exposing _ivars in header files is
gross. You never want people to access them directly, so don't make
those declarations public at all. Exposing _ivars without properties
in .m files is also gross, as it is not clear whether those
relationships are supposed to be strong or weak.
2) Technically, nothing is truly private in Objective-C, so let's stop
trying to completely prevent people from using private APIs. Let's
just adopt a convention that is clear and lets people know that if
they use private APIs they do so at their own risk.
3) Protected and private APIs (including ivars) should not
autocomplete most of the time in Xcode, so they should not be in the
public header file at all. We want the header file to be clear,
concise, and very readable.

Given those decisions, here is how we currently do things:

* Public ivars are always declared as properties in the class header
file. The _ivar should not be declared in the header file at all. Let
the synthesizers declare them in the .m file. _ivars needlessly
complicate the public header files for your classes, so keep them out.
* Don't be afraid to mark many of your public properties as readonly.
You can always override the property declaration as being readwrite in
a class extension in the .m file.
* Private ivars are declared as private @properties in the .m file.
Again, let the synthesizers actually declare the _ivar. Don't declare
the _ivars yourself, as it won't be immediately clear whether the
references are supposed to be strong or weak. Use properties!
* Protected methods and properties are tricky. We want subclasses to
be able to access these directly, but we don't want API consumers to
see them when autocompleting in Xcode or when looking at the public
header file. So, we decided to do what Apple does with
UIGestureRecognizerSubclass.h. We create a special header file that
defines all of the protected properties and methods of a class using a
category. Then, any subclass implementation files can import this file
to easily access those protected APIs. Yes, nothing is stopping a bad
developer from importing this header file and using protected APIs
when they shouldn't, but they are hidden in a different file and
appropriately documented so that developers don't accidentally use
them.

There are many ways to handle public, private, and protected APIs in
Objective-C. We have found this to be a clean approach that works for
us.

- Sebastian
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Charles Srstka
On Mar 19, 2012, at 7:28 PM, William Squires wrote:

> The fact that the header declares your IBOutlets and IBActions is 
> intentional, otherwise your design would be too-tightly coupled; this isn't 
> good... Not only does IB need to know where the outlets and actions are, so 
> do any other designers (including yourself at a later date) who then want to 
> make an alternate view on your data; all they need to is connect the new view 
> (xib) to your existing controller and wire up the outlets and actions.

The thing about that is, in the latest versions of Xcode, IB *doesn’t* need 
IBOutlets and IBActions to be in the header. You can put this stuff in the .m 
file, and IB finds it just fine.

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread William Squires

On Mar 16, 2012, at 4:00 PM, Brian Lambert wrote:

> I’ve been developing iOS applications full-time for about 6 months now and
> I love it. I feel pretty strong on the platform now.
> 
> I have a lingering question about something that’s really been bugging the
> heck out of me, though, that I thought I would ask the list and get some
> feedback on.
> 
> It seems to be the case that when people are developing a UIViewController
> subclass or a UIView subclass that they expose *all* the implementation
> details of that class through public properties vs. using ivars.
> 
> Here’s an example. For the purpose of this post, I’ve wrote a simple iPhone
> app with one view. The link below is a screen shot of it:
> 
> https://s3.amazonaws.com/Softwarenerd/MyApp.jpg
> 
> For now, I used Interface Builder to generate the UI.  In doing so, I wound
> up with:
> 
> #import 
> 
> // MyViewController interface.
> @interface MyViewController : UIViewController
> 
> // Properties.
> @property (weak, nonatomic) IBOutlet UILabel * labelMyLabel;
> 
> // buttonDoItTouchUpInside action.
> - (IBAction)buttonDoItTouchUpInside:(id)sender;
> 
> @end
> 
> This means that my UILabel called labelMyLabel is publicly available.
> Anyone who has access to an instance of MyViewController can do anything
> they want to with my label, including replacing it.
> 
> Also, anyone who has an instance of MyViewController can call my
> buttonDoItTouchUpInside action.
> 
> For example, in my AppDelegate, I can do:
> 
> - (BOOL)application:(UIApplication *)application
> didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
> {
>   self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]
> bounds]];
> 
>   MyViewController * myViewController = [[MyViewController alloc]
> initWithNibName:@"MyViewController" bundle:nil];
>   [self setMyViewController:myViewController];
>   [[self window] setRootViewController:[self myViewController]];
>   [[self window] makeKeyAndVisible];
> 
>   // Mess with MyViewController  HAHAHAHA FU, MyViewController
>   [[myViewController labelMyLabel] setText:@"This is ridiculous"];
>   return YES;
> }
> 
> To me, this totally ridiculous. It breaks well-established rules of
> encapsulation.
> 
  In part, I see your problem (the interface is just meant for IB, not for 
other programmers), but remember, the point of a controller object is to 
mediate between some view object (which may have subviews, etc...) and one or 
more model objects. The fact that the header declares your IBOutlets and 
IBActions is intentional, otherwise your design would be too-tightly coupled; 
this isn't good. Remember, MVC is a paradigm, not a hard-and-fast, set-in-stone 
set of laws. There are times when you should (and need to) break some of the 
design principles in order to uphold others; it all depends on what your design 
is attempting to do. Not only does IB need to know where the outlets and 
actions are, so do any other designers (including yourself at a later date) who 
then want to make an alternate view on your data; all they need to is connect 
the new view (xib) to your existing controller and wire up the outlets and 
actions. Sometimes we have to make trade-offs in order to get a design that 
works. In this case, the trade-off is exposing outlets and actions to possible 
code misuse, in order to be able to use a visual builder (IB) to make our user 
interfaces in a straight-forward manner.
  It's also part of what makes a dynamic language like ObjC so powerful; but - 
as always - with power comes responsibility. You could - if needed - substitute 
a UILabel subclass for the original, and your controller wouldn't know the 
difference, since - to it - what it has a reference to IS a UILabel, and acts 
like a UILabel, so it must be a UILabel! This is sometimes referred to as 'duck 
typing'; if it looks like a duck and acts like a duck, it's probably a duck; 
use it as such.
  HTH!
  Also, this post really belongs on the Cocoa list as this is a programming 
sort of problem, not a problem with Xcode usability.

> From my analysis, it appears to be nothing more than an artifact of how
> rehydrating NIBs works, and it totally compromises good OO software design
> by leaking all the implementation details of MyViewController to the
> outside world.
> 
> Everyone, all the books, training materials, samples, and so on, just seem
> to accept this style of doing things as being normal. In fact, one book I
> read *encouraged* this technique of using public properties for ALL the
> internal state of a class over using ivars. It said public properties were
> preferable.
> 
  Here I agree with you; not everything should be public, just outlets and 
actions, or any model you need bindings too (or KVC/KVO compliance). Else, make 
it @private, or - better yet - make a named category at the top of your 
implementation file if you have any methods you don't want exposed to the 
outside world. Even if you put them in an @private

Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Matt Neuburg

On Mar 19, 2012, at 12:45 PM, Brian Lambert wrote:

> ivars in the .H file of my Foo class, which no one other than me will ever 
> use, should be relatively OK.  After all, I'm not trying to prevent myself 
> from knowing anything about my implementation of Foo.  I'm just trying to 
> ensure that my *intent* for my class is well-understood to other programmers 
> who will work on Foo in the future.

In my experience, that's not a good way to think about what writing an OO 
program. (1) The main programmer who may work on Foo in the future may be me, 
but I think of him as one of those "other programmers". I can guarantee that I 
won't have the slightest idea what this program does or why my intent was, 
probably as soon as tomorrow, if I don't express it clearly in the program 
itself. (2) OOP is about expressing contracts. Now that ivars that are not 
intended as part of the public face of a class no longer have to be in the 
header file, it's best to take advantage of it if possible so that the program 
expresses the intended architecture.

Here's a case where declaring the ivars in the implementation file wouldn't 
have worked for me:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch37p920downloader/p754p772downloader/MyDownloaderPrivateProperties.h

Okay, it's properties not ivars, but the idea is the same. I want a subclass of 
MyDownloader to know about these properties. The way to do that is to declare 
them in a class extension and have the subclass (MyImageDownloader) import the 
file with that class extension.

Hope that helps -

m. 

--
matt neuburg, phd = m...@tidbits.com, http://www.apeth.net/matt/
pantes anthropoi tou eidenai oregontai phusei
Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
TidBITS, Mac news and reviews since 1990, http://www.tidbits.com



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Greg Parker
On Mar 19, 2012, at 12:27 PM, Brian Lambert  wrote:
> Regarding this:
> 
>In the chapter called "Defining a Class", not only is declaring
>an ivar in the .m file covered, but doing it in the .h file is downright
>discouraged (rightly so). In practice, this feature of Objective-C...
> 
> I can't stand thus sort of subtle crap.  If it's legal to declare ivars in
> the .M file and the .H file, it's crap to say it's "discouraged" in the .H
> file.  Either a language is well-designed, consistent, and carefully
> thought out, or, it has turned into crap.

No, it's a flexibility vs complexity tradeoff. We could change the language to 
make it impossible to declare ivars in a .h file, but then you lose the ability 
to write higher-performance struct-like classes. Similarly, we could make it 
impossible to declare ivars in a .m file, but then you lose the ability to 
write framework classes without exposing these implementation details. Both 
cases are useful. One of them happens to be better in most cases, so we 
"discourage" the other unless you really need it.


> Is there a warning level for "You did something that's totally legal, but,
> discouraged."?

There are warnings of this form. For example, if you perform an assignment 
inside an `if` condition, the compiler will warn about it on the assumption 
that you probably meant to perform a comparison instead. The problem with this 
sort of warning is that there needs to be a clean way to say "no really, do the 
discouraged thing" to pacify the compiler.


> I love Objective-C Category files because they
> allow me to segment my implementation such that each file more or less
> represents each interface that my class implements

We like this too; it's commonly used inside system frameworks for large classes 
like NSWindow. In a recent version of Xcode we added optimizations to the 
linker so that there's no longer any extra runtime overhead if you write 
categories on your own classes in the same binary. 


> Is there a way to declare ivars in the .M file AND have them accessible
> from Objective-C Category files for the class?

You can keep ivars out of your public .h file and use them in categories. 
First, declare the ivars as @package in a class extension in another header 
file. Then #include that header file in your class implementation and your 
category implementations.

// MyClass.h
@interface MyClass : SomeSuperclass {
// look ma, no ivars
}
@end

// MyClass-Internal.h
#import "MyClass.h"
@interface MyClass () {  // class extension
  @package
int anIvar;
}
@end

// MyClass.m
#import "MyClass-Internal.h"
@implementation MyClass
...
@end

// MyClass-Category.m
#import "MyClass-Internal.h"
@implementation MyClass (Category)
-(int)method { return anIvar; }
@end


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Charles Srstka
On Mar 19, 2012, at 2:27 PM, Brian Lambert wrote:

> Is there a way to declare ivars in the .M file AND have them accessible
> from Objective-C Category files for the class?

Use an extension instead of a category?

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Brian Lambert
One final note:

ivars in the .H file of a public framework is *obviously stupid* as it
leaks implementation details.

ivars in the .H file of my Foo class, which no one other than me will ever
use, should be relatively OK.  After all, I'm not trying to prevent myself
from knowing anything about my implementation of Foo.  I'm just trying to
ensure that my *intent* for my class is well-understood to other
programmers who will work on Foo in the future.


On Mon, Mar 19, 2012 at 12:27 PM, Brian Lambert wrote:

> I'd like an argument, please.
>
> Regarding this:
>
> In the chapter called "Defining a Class", not only is declaring
> an ivar in the .m file covered, but doing it in the .h file is
> downright
> discouraged (rightly so). In practice, this feature of Objective-C...
>
> I can't stand thus sort of subtle crap.  If it's legal to declare ivars in
> the .M file and the .H file, it's crap to say it's "discouraged" in the .H
> file.  Either a language is well-designed, consistent, and carefully
> thought out, or, it has turned into crap.
>
> Is there a warning level for "You did something that's totally legal, but,
> discouraged."?
>
> ivars in the .H file are totally necessary in order to use ivars with
> Objective-C Category files.  I love Objective-C Category files because they
> allow me to segment my implementation such that each file more or less
> represents each interface that my class implements, vs, loading *all* the
> implementation details into one .M file simply so I don't have to declare
> ivars in the .H file.
>
> I get why ivars in the .H file is not super fantastic, so let's not have
> that debate.
>
> Is there a way to declare ivars in the .M file AND have them accessible
> from Objective-C Category files for the class?
>
> Thanks!
>
> Brian
>
>
> On Mon, Mar 19, 2012 at 11:32 AM, Matt Neuburg  wrote:
>
>> On Fri, 16 Mar 2012 17:11:24 -0400, Marco Tabini  said:
>> >> That time has passed now, so you can now completely specify IBOutlets
>> (and IBActions) in your implementation file and hide the details from the
>> outside world. If you want properties, you can use a class extension like
>> so to add them:
>> >
>> >Sorry to hijack this conversation, but I've been meaning to ask: Where
>> is this documented? I stumbled on this feature (and the ability to declare
>> ivars directly in the .m file), but I didn't see it explained it anywhere.
>> I'm sure I'm just not looking in the right place, but I can't find it
>> anywhere.
>>
>> See Apple's document "The Objective-C Programming Language".
>>
>> In the chapter called "Defining a Class", not only is declaring an ivar
>> in the .m file covered, but doing it in the .h file is downright
>> discouraged (rightly so). In practice, this feature of Objective-C did not
>> swim into most people's ken until Xcode 4.2, when LLVM because the default
>> compiler.
>>
>> In the chapter called "Categories and Extensions", declaration of private
>> properties is discussed. That feature is considerably older.
>>
>> m.
>>
>> PS And of course there's also my book, which makes much of these features.
>>
>> PPS The trouble with language improvements like this, and with documents
>> like The Objective-C Programming Language, is that there's a terminus point
>> somewhere and they don't tell you exactly when it is. What I mean is, you
>> can surprise yourself by adopting an improvement of this sort and then
>> opening your project in an earlier version of Xcode that doesn't understand
>> it. Also, different *parts* of Xcode may not understand it; for example,
>> your code will compile, but the feature where you can drag from an ivar to
>> the nib editor to form an outlet might not work (though now, I believe, it
>> does).
>>
>> --
>> matt neuburg, phd = m...@tidbits.com, 
>> A fool + a tool + an autorelease pool = cool!
>> Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
>> ___
>>
>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>> https://lists.apple.com/mailman/options/cocoa-dev/brianlambert%40gmail.com
>>
>> This email sent to brianlamb...@gmail.com
>>
>
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Brian Lambert
I'd like an argument, please.

Regarding this:

In the chapter called "Defining a Class", not only is declaring
an ivar in the .m file covered, but doing it in the .h file is downright
discouraged (rightly so). In practice, this feature of Objective-C...

I can't stand thus sort of subtle crap.  If it's legal to declare ivars in
the .M file and the .H file, it's crap to say it's "discouraged" in the .H
file.  Either a language is well-designed, consistent, and carefully
thought out, or, it has turned into crap.

Is there a warning level for "You did something that's totally legal, but,
discouraged."?

ivars in the .H file are totally necessary in order to use ivars with
Objective-C Category files.  I love Objective-C Category files because they
allow me to segment my implementation such that each file more or less
represents each interface that my class implements, vs, loading *all* the
implementation details into one .M file simply so I don't have to declare
ivars in the .H file.

I get why ivars in the .H file is not super fantastic, so let's not have
that debate.

Is there a way to declare ivars in the .M file AND have them accessible
from Objective-C Category files for the class?

Thanks!

Brian


On Mon, Mar 19, 2012 at 11:32 AM, Matt Neuburg  wrote:

> On Fri, 16 Mar 2012 17:11:24 -0400, Marco Tabini  said:
> >> That time has passed now, so you can now completely specify IBOutlets
> (and IBActions) in your implementation file and hide the details from the
> outside world. If you want properties, you can use a class extension like
> so to add them:
> >
> >Sorry to hijack this conversation, but I've been meaning to ask: Where is
> this documented? I stumbled on this feature (and the ability to declare
> ivars directly in the .m file), but I didn't see it explained it anywhere.
> I'm sure I'm just not looking in the right place, but I can't find it
> anywhere.
>
> See Apple's document "The Objective-C Programming Language".
>
> In the chapter called "Defining a Class", not only is declaring an ivar in
> the .m file covered, but doing it in the .h file is downright discouraged
> (rightly so). In practice, this feature of Objective-C did not swim into
> most people's ken until Xcode 4.2, when LLVM because the default compiler.
>
> In the chapter called "Categories and Extensions", declaration of private
> properties is discussed. That feature is considerably older.
>
> m.
>
> PS And of course there's also my book, which makes much of these features.
>
> PPS The trouble with language improvements like this, and with documents
> like The Objective-C Programming Language, is that there's a terminus point
> somewhere and they don't tell you exactly when it is. What I mean is, you
> can surprise yourself by adopting an improvement of this sort and then
> opening your project in an earlier version of Xcode that doesn't understand
> it. Also, different *parts* of Xcode may not understand it; for example,
> your code will compile, but the feature where you can drag from an ivar to
> the nib editor to form an outlet might not work (though now, I believe, it
> does).
>
> --
> matt neuburg, phd = m...@tidbits.com, 
> A fool + a tool + an autorelease pool = cool!
> Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
> ___
>
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/brianlambert%40gmail.com
>
> This email sent to brianlamb...@gmail.com
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Matt Neuburg
On Fri, 16 Mar 2012 17:11:24 -0400, Marco Tabini  said:
>> That time has passed now, so you can now completely specify IBOutlets (and 
>> IBActions) in your implementation file and hide the details from the outside 
>> world. If you want properties, you can use a class extension like so to add 
>> them:
>
>Sorry to hijack this conversation, but I've been meaning to ask: Where is this 
>documented? I stumbled on this feature (and the ability to declare ivars 
>directly in the .m file), but I didn't see it explained it anywhere. I'm sure 
>I'm just not looking in the right place, but I can't find it anywhere.

See Apple's document "The Objective-C Programming Language".

In the chapter called "Defining a Class", not only is declaring an ivar in the 
.m file covered, but doing it in the .h file is downright discouraged (rightly 
so). In practice, this feature of Objective-C did not swim into most people's 
ken until Xcode 4.2, when LLVM because the default compiler.

In the chapter called "Categories and Extensions", declaration of private 
properties is discussed. That feature is considerably older.

m.

PS And of course there's also my book, which makes much of these features.

PPS The trouble with language improvements like this, and with documents like 
The Objective-C Programming Language, is that there's a terminus point 
somewhere and they don't tell you exactly when it is. What I mean is, you can 
surprise yourself by adopting an improvement of this sort and then opening your 
project in an earlier version of Xcode that doesn't understand it. Also, 
different *parts* of Xcode may not understand it; for example, your code will 
compile, but the feature where you can drag from an ivar to the nib editor to 
form an outlet might not work (though now, I believe, it does).

--
matt neuburg, phd = m...@tidbits.com, 
A fool + a tool + an autorelease pool = cool!
Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-19 Thread Matt Neuburg
On Sat, 17 Mar 2012 01:45:33 -0700, G S  said:
>>
>> This pattern is pretty questionable though in terms of OO — you have one
>> class (NSNib, UINib, etc.) directly setting instance variables in another
>> class (your view controller) and using runtime functions to hack around
>> things like @private.
>>
>
>How do you figure?  I'm not doing any manipulation of non-property members
>between classes.  If you're saying that Cocoa does it when loading from a
>nib, then it's doing that anyway; properties aren't required for that
>action.  From the end-user (end-programmer) perspective, I don't see any
>bad OO going on here.

So we're talking about just declaring an IBOutlet ivar and letting the nib set 
it via KVC (in iOS)? The problem with that is that before ARC you could really 
mess yourself up with that pattern, as there is an **implicit retain** 
performed by KVC when it access an ivar directly, which you're not told about 
and which may not be at all what you want.

So you've got this:

IBOutlet MyClass* myIvar;

...just sitting there, with *no* retain policy declaration and thus nothing to 
remind you that you need to release that ivar in your dealloc or it's going to 
leak.

For all the faults of @property declarations (well discussed in a different 
thread on this list), they are certainly helpful for reminding you, the 
programmer, how memory is supposed to be managed thru the accessor. And before 
ARC you could say this:

@property (nonatomic, assign) MyClass* myIvar;

...and synthesize the accessors, and by jingo this would actually *be* an 
assign-policy setter (no retain), which, for something loaded from a nib, is 
very often what you want. So the property declaration actually **guards against 
KVC interfering with your memory management**.

Therefore, my current pattern is to declare my nonpublic properties in a class 
extension in the .m file. This is so common that in Xcode 4.3 the iOS project 
templates actually give you a class extension in the .m file so you can do that 
- though, to be sure, the templates do some other memory management stuff that 
I don't agree with.

Now, of course with ARC things are greatly simplified, and they're going to be 
simplified even more when synthesis of accessors is the default. Also I wish 
nonatomic were the default, but that's another story I suppose... m.

--
matt neuburg, phd = m...@tidbits.com, 
A fool + a tool + an autorelease pool = cool!
Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-17 Thread Charles Srstka
On Mar 17, 2012, at 6:47 AM, G S wrote:

> That kind of behind-the-scenes stuff really doesn't worry me too much, since 
> there are all kinds of hacky, non-OO things taking place in this language.  
> I'm not denigrating you for trying to avoid as much of it as possible, but it 
> seems like there's more of it going on than one can practically prevent.

Other than the awful misfeature of KVO accessing ivars directly, which I also 
recommend against using, I can’t think of too many other examples of a class 
monkeying with another class’s private instance variables off the top of my 
head.

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-17 Thread G S
>
> How do you think that (NS)|(UI)Nib — an unrelated class that shouldn’t
> have access to your private ivars — sets the outlet variables to your nib
> objects? It does it via runtime hackery. If you declare a property, on the
> other hand, it just calls the setter. Much cleaner and more OO, if you ask
> me.
>

Interesting.  I went and read up on NSNib and learned some stuff, so thanks
for the reference.

That kind of behind-the-scenes stuff really doesn't worry me too much,
since there are all kinds of hacky, non-OO things taking place in this
language.  I'm not denigrating you for trying to avoid as much of it as
possible, but it seems like there's more of it going on than one can
practically prevent.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-17 Thread Charles Srstka
On Mar 17, 2012, at 3:45 AM, G S wrote:

> This pattern is pretty questionable though in terms of OO — you have one 
> class (NSNib, UINib, etc.) directly setting instance variables in another 
> class (your view controller) and using runtime functions to hack around 
> things like @private.
> 
> How do you figure?  I'm not doing any manipulation of non-property members 
> between classes.  If you're saying that Cocoa does it when loading from a 
> nib, then it's doing that anyway; properties aren't required for that action. 
>  From the end-user (end-programmer) perspective, I don't see any bad OO going 
> on here.

So you have an ivar marked @private. How do you think that (NS)|(UI)Nib — an 
unrelated class that shouldn’t have access to your private ivars — sets the 
outlet variables to your nib objects? It does it via runtime hackery. If you 
declare a property, on the other hand, it just calls the setter. Much cleaner 
and more OO, if you ask me.

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-17 Thread G S
>
> This pattern is pretty questionable though in terms of OO — you have one
> class (NSNib, UINib, etc.) directly setting instance variables in another
> class (your view controller) and using runtime functions to hack around
> things like @private.
>

How do you figure?  I'm not doing any manipulation of non-property members
between classes.  If you're saying that Cocoa does it when loading from a
nib, then it's doing that anyway; properties aren't required for that
action.  From the end-user (end-programmer) perspective, I don't see any
bad OO going on here.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-17 Thread Charles Srstka
On Mar 16, 2012, at 9:16 PM, G S wrote:

> Thanks for asking this, Brian.  I've wondered the same thing, and in fact I
> went through my code and removed almost all property declarations from my
> view controllers.  Since most properties are declared as "retain", you're
> just increasing your bookkeeping to avoid leaks.  Not to mention the sheer
> maintenance hassle of typing out or deleting the declarations as you add or
> remove members.
> 
> And as someone pointed out, properties are not at all necessary for making
> connections in IB.  So I don't see the point.  Now I'm referring to the
> members directly, with the added bonus of being able to use member notation
> to identify members for clarity.

This pattern is pretty questionable though in terms of OO — you have one class 
(NSNib, UINib, etc.) directly setting instance variables in another class (your 
view controller) and using runtime functions to hack around things like 
@private. That’s really icky — using properties seems like a much cleaner way 
to do it. The property can be declared in a class extension in the .m file, and 
it’s not like typing

@property IBOutlet NSButton *foo;

is that much harder than typing

{
@private
IBOutlet NSButton *_foo;
}

when it comes down to it.

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread G S
Thanks for asking this, Brian.  I've wondered the same thing, and in fact I
went through my code and removed almost all property declarations from my
view controllers.  Since most properties are declared as "retain", you're
just increasing your bookkeeping to avoid leaks.  Not to mention the sheer
maintenance hassle of typing out or deleting the declarations as you add or
remove members.

And as someone pointed out, properties are not at all necessary for making
connections in IB.  So I don't see the point.  Now I'm referring to the
members directly, with the added bonus of being able to use member notation
to identify members for clarity.

Regards,
Gavin
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Ian Joyner
This is an interesting discussion, but there is a lot of misunderstanding of 
the concept of information hiding if not in what has been said here, but 
generally in the industry. This term was introduced by David Parnas, and I 
think it is a bit unfortunate because if you read his papers on this he really 
means implementation hiding:

On the Criteria to be used in Decomposing Systems into Modules (1972):

http://www-sst.informatik.tu-cottbus.de/~db/doc/People/Broy/Software-Pioneers/Parnas_hist.pdf

The Secret History of Information Hiding (2002):

http://www-sst.informatik.tu-cottbus.de/~db/doc/People/Broy/Software-Pioneers/Parnas_new.pdf

There is something deeper to this than simply hiding variables. A lot of people 
using C++, Java, etc think it means hiding data behind get and set routines. 
However, in reality we are trying to expose data, we are just trying to do it 
in an implementation independent manner. Thus it is the interface (API) is the 
important part of the design.

A corollary of this is Bertrand Meyer's Principle of Uniform Access, which says 
values should be provided to a caller in a uniform way, no matter whether the 
data comes from storage (variable), is computed either in an expression or a 
function:

http://en.wikipedia.org/wiki/Uniform_access_principle

http://martinfowler.com/bliki/UniformAccessPrinciple.html

I think Martin Fowler's article clearly shows Parnas's ideas.

Objective-C implements this principle of uniform access with properties.

Ian

On 17 Mar 2012, at 08:56, Conrad Shultz wrote:

> On 3/16/12 2:00 PM, Brian Lambert wrote:
>> This means that my UILabel called labelMyLabel is publicly available.
>> Anyone who has access to an instance of MyViewController can do anything
>> they want to with my label, including replacing it.
>> 
>> Also, anyone who has an instance of MyViewController can call my
>> buttonDoItTouchUpInside action.
> 
> In addition to David's remarks, it should also be noted that there isn't
> really any concept of "private" properties or methods (in the enforced
> sense) in Objective-C due to the dynamic nature of the language and
> runtime.  No matter where you *declare* your properties and/or methods,
> what you state above would always be possible.
> 
> (As an aside, major features in Cocoa rely on fairly crazy runtime
> manipulation.  For example, key-value observing:
> http://mikeash.com/pyblog/friday-qa-2009-01-23.html)
> 
> Suppose you wanted to peek under a class' hood (for curiosity's sake, of
> course; private API usage is generally a bad idea and is explicitly
> forbidden in the App Stores and from discussion on the official mailing
> lists).  To see a class' properties (both from itself and its protocols)
> you could try something along the lines of (warning: a thrown together
> quick hack, probably has bugs):
> 
>unsigned int propertyCount;
>objc_property_t *allProperties = class_copyPropertyList([MyClassName
> class], &propertyCount);
>for (NSUInteger i = 0; i < propertyCount; i++) {
>const char *name = property_getName(allProperties[i]);
>NSLog(@"%s", name);
>}
> 
>unsigned int protocolCount;
>Protocol **allProtocols = class_copyProtocolList([MyClassName
> class], &protocolCount);
>for (NSUInteger i = 0; i < protocolCount; i++) {
>const char *protocol = protocol_getName(allProtocols[i]);
>NSLog(@"PROTOCOL %s", protocol);
>unsigned int protoPropertyCount;
>objc_property_t *protoProperties =
> protocol_copyPropertyList(allProtocols[i], &protoPropertyCount);
>for (NSUInteger j = 0; j < protoPropertyCount; j++) {
>const char *propName = property_getName(protoProperties[j]);
>NSLog(@"\t%s", propName);
>}
>}
> 
> This and other fun hackery is documented in the Runtime Programming
> Guide:
> https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide
> 
> 
> 
> -- 
> Conrad Shultz
> 
> Synthetiq Solutions
> www.synthetiqsolutions.com
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/ianjoyner%40me.com
> 
> This email sent to ianjoy...@me.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Luther Baker
A few points worth clarifying for the original poster here ...

Using a @property does NOT actually expose the underlying implementation.
@properties are like configurable ACCESSORS ... they do *NOT* necessarily
provide direct access to the implementation. You can implement them however
you want. You can @synthesize them, make them readonly, return something
computed from them ... or do all sorts of work when trying to "set" them.

It is really up to you to be careful what you decide to expose. Consider
that in Java, one must often write

public void setName(String name) { this.name = name; }
public String getName() { return this.name}

@properties can give you this type of behavior in a 'declaratory' way. They
are actually very powerful as this is only *one* example of how they can be
used. Consider attributes such as assign, readonly, atomic ... there are
loads of semantics that you can apply to your accessors by changing just a
few words in one line:

@property (readonly) NSString *name;

Dig into them 
here.
They
are more than just a convenience. They are succinct. They are
self-describing. If used correctly - they are very very consistent with
standard OO practices. You can think of them as syntactic sugar for
well-known and used OO patterns - but some would suggest they are much more
powerful than that.

And with respect to your original IB implementation, note that Interface
Builder can bind to ivars that are not formally declared as @property. For
example, you may do this:

@interface MyViewController {
@private
IBOutlet UILabel *labelMyLabel;
IBOutlet UIButton *buttonDoIt;
}

The ivars are not exposed, IB finds them ... all is well - and the code
looks more or less like any other OO language that declares the ivars in
the headers. Now, whether or not THAT is a good practice is a different
debate and has implications far beyond the scope of Objective-C or Cocoa
for that matter (ie: declaring ivars in the implementation files).

Security and runtime implications aside, you can write excellent OO code
with a liberal use of @properties in Objective-C but as Bjarne once
said:
"*C makes it easy to shoot yourself in the foot; C++ makes it harder, but
when you do it blows your whole leg off" *and likewise, @properties can be
abused if not understood or used incorrectly.

Hope that helps,
-Luther




On Fri, Mar 16, 2012 at 5:53 PM, Jens Alfke  wrote:

>
> On Mar 16, 2012, at 2:57 PM, Eeyore wrote:
>
> > So simply hiding the actions in the implementation doesn't protect you
> from finding out the method's name and calling it.
>
> Well, sure. If you’re in the same process, there’s nothing protecting you
> from malicious code. The same goes for C++ or assembly; it’s just a little
> easier to find the method’s entry point in Obj-C because there’s more
> metadata.
>
> The point of not declaring internal methods in the header isn’t for
> security, it’s to prevent accidentally using internal APIs in places where
> you shouldn’t. If a class considers property X as part of its internal
> state, then other code in the project shouldn’t use X, so you want to make
> sure that accidentally referring to X produces a compile error.
>
> —Jens
>
> ___
>
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/lutherbaker%40gmail.com
>
> This email sent to lutherba...@gmail.com
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread George Toledo

On Mar 16, 2012, at 6:53 PM, cocoa-dev-requ...@lists.apple.com wrote:

> Date: Fri, 16 Mar 2012 15:53:30 -0700
> From: Jens Alfke 
> To: Eeyore 
> Cc: cocoa-dev list 
> Subject: Re: Why so many public properties all up in my grizzle?
> Message-ID: <4aba472f-cdad-47f3-8544-a5538f5ac...@mooseyard.com>
> Content-Type: text/plain; charset=windows-1252
> 
> 
> On Mar 16, 2012, at 2:57 PM, Eeyore wrote:
> 
>> So simply hiding the actions in the implementation doesn't protect you from 
>> finding out the method's name and calling it.
> 
> Well, sure. If you’re in the same process, there’s nothing protecting you 
> from malicious code. The same goes for C++ or assembly; it’s just a little 
> easier to find the method’s entry point in Obj-C because there’s more 
> metadata.

... and of course, even not in the case of hackers who are wanting to do 
malicious things, if any curious party can get the compiled code, they can take 
the time to reverse engineer it from assembly. IMO, it's generally a waste of 
time to try to spend too much time "hiding" things, because they're all hanging 
out there in the compiled code anyway :-)

-gt

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Jens Alfke

On Mar 16, 2012, at 2:57 PM, Eeyore wrote:

> So simply hiding the actions in the implementation doesn't protect you from 
> finding out the method's name and calling it.

Well, sure. If you’re in the same process, there’s nothing protecting you from 
malicious code. The same goes for C++ or assembly; it’s just a little easier to 
find the method’s entry point in Obj-C because there’s more metadata.

The point of not declaring internal methods in the header isn’t for security, 
it’s to prevent accidentally using internal APIs in places where you shouldn’t. 
If a class considers property X as part of its internal state, then other code 
in the project shouldn’t use X, so you want to make sure that accidentally 
referring to X produces a compile error.

—Jens

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Eeyore
David Duncan indicates that some of this can be alleviated with newer runtimes, 
but Objective C's messaging system allows you to send messages to objects even 
if those messages are not declared in the object's interface. So simply hiding 
the actions in the implementation doesn't protect you from finding out the 
method's name and calling it.

Another issue (not Obj-C specific) is that all the frameworks that I've used 
that connect graphically developed UIs with code required the classes to expose 
the point of connection. Your completely coded example is a little more 
protected from malicious coders, but not completely, as a hacker would still 
have access to the controller's view and could walk the subviews making 
changes. The convenience I get by being able to lay my views out graphically 
comes at the expense of requiring me to expose my outlets (so that the system 
can connect my code and my nib). I don't think there could be any way for the 
system to make those connections without making the outlets publicly available.

Specific comments on your example, below:

On Mar 16, 2012, at 2:00 PM, Brian Lambert wrote:

> #import 
> 
> // MyViewController interface.
> @interface MyViewController : UIViewController
> 
> // Properties.
> @property (weak, nonatomic) IBOutlet UILabel * labelMyLabel;

I suspect that the UILabel ought to be strong, but that's not really the topic 
here.

> // buttonDoItTouchUpInside action.
> - (IBAction)buttonDoItTouchUpInside:(id)sender;
> 
> @end
> 
> This means that my UILabel called labelMyLabel is publicly available.
> Anyone who has access to an instance of MyViewController can do anything
> they want to with my label, including replacing it.

In your implementation, you (probably) have something like

@synthesize labelMyLabel=_labelMyLabel;

This means that labelMyLabel may be public but the actual data _labelMyLabel is 
private. If you are really concerned about someone tinkering with the 
labelMyLabel, you can try to intercept access to labelMyLabel by implementing 
your own custom getter/setter. But if you want the runtime to connect your 
label to your class, you are going to need to allow outsiders to set your label 
at some point (possibly repeatedly as your view unloads and loads due to memory 
warnings).

> Also, anyone who has an instance of MyViewController can call my
> buttonDoItTouchUpInside action.

If you don't want to expose this, then you can expose the button through a 
IBOutlet and manually connect the action in viewDidLoad. I actually prefer to 
connect actions manually because then if I have multiple nibs for the same 
class (e.g., an iPhone and an iPad nib for the same controller), I don't have 
to try to remember to set all the actions, just the outlets.

> Everyone, all the books, training materials, samples, and so on, just seem
> to accept this style of doing things as being normal. In fact, one book I
> read *encouraged* this technique of using public properties for ALL the
> internal state of a class over using ivars. It said public properties were
> preferable.

The ivars are your data, the properties are just getter/setter methods that 
access that data (with some syntactic sugar that makes it look like data 
access). I would guess that the author was suggesting to make all data access 
go through getter/setter properties instead of direct ivar access. I think they 
were comparing "public property vs. public ivar" and proposing the use of 
public properties (getter/setters) instead of direct data manipulation.

Aaron




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Conrad Shultz
On 3/16/12 2:00 PM, Brian Lambert wrote:
> This means that my UILabel called labelMyLabel is publicly available.
> Anyone who has access to an instance of MyViewController can do anything
> they want to with my label, including replacing it.
> 
> Also, anyone who has an instance of MyViewController can call my
> buttonDoItTouchUpInside action.

In addition to David's remarks, it should also be noted that there isn't
really any concept of "private" properties or methods (in the enforced
sense) in Objective-C due to the dynamic nature of the language and
runtime.  No matter where you *declare* your properties and/or methods,
what you state above would always be possible.

(As an aside, major features in Cocoa rely on fairly crazy runtime
manipulation.  For example, key-value observing:
http://mikeash.com/pyblog/friday-qa-2009-01-23.html)

Suppose you wanted to peek under a class' hood (for curiosity's sake, of
course; private API usage is generally a bad idea and is explicitly
forbidden in the App Stores and from discussion on the official mailing
lists).  To see a class' properties (both from itself and its protocols)
you could try something along the lines of (warning: a thrown together
quick hack, probably has bugs):

unsigned int propertyCount;
objc_property_t *allProperties = class_copyPropertyList([MyClassName
class], &propertyCount);
for (NSUInteger i = 0; i < propertyCount; i++) {
const char *name = property_getName(allProperties[i]);
NSLog(@"%s", name);
}

unsigned int protocolCount;
Protocol **allProtocols = class_copyProtocolList([MyClassName
class], &protocolCount);
for (NSUInteger i = 0; i < protocolCount; i++) {
const char *protocol = protocol_getName(allProtocols[i]);
NSLog(@"PROTOCOL %s", protocol);
unsigned int protoPropertyCount;
objc_property_t *protoProperties =
protocol_copyPropertyList(allProtocols[i], &protoPropertyCount);
for (NSUInteger j = 0; j < protoPropertyCount; j++) {
const char *propName = property_getName(protoProperties[j]);
NSLog(@"\t%s", propName);
}
}

This and other fun hackery is documented in the Runtime Programming
Guide:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide



-- 
Conrad Shultz

Synthetiq Solutions
www.synthetiqsolutions.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Marco Tabini
> That time has passed now, so you can now completely specify IBOutlets (and 
> IBActions) in your implementation file and hide the details from the outside 
> world. If you want properties, you can use a class extension like so to add 
> them:

Sorry to hijack this conversation, but I've been meaning to ask: Where is this 
documented? I stumbled on this feature (and the ability to declare ivars 
directly in the .m file), but I didn't see it explained it anywhere. I'm sure 
I'm just not looking in the right place, but I can't find it anywhere.

Cheers,


Marco
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread Kyle Sluder
Please don't crosspost. Choose one list.

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Why so many public properties all up in my grizzle?

2012-03-16 Thread David Duncan
On Mar 16, 2012, at 2:00 PM, Brian Lambert wrote:

> 
> To me, this is how things should be. The implementation details of how my
> view works are hidden.
> 
> Am I missing something?


Part of the problem was that prior to Xcode 4, IBOutlets needed to be declared 
in the header, or Interface Builder wouldn't find them (ditto for IBActions). 
As such the best you could do was declare the instance variables in the header 
and pre-pend them with IBOutlet, then declare your properties in a class 
extension.

That time has passed now, so you can now completely specify IBOutlets (and 
IBActions) in your implementation file and hide the details from the outside 
world. If you want properties, you can use a class extension like so to add 
them:

@interface ViewController()

@property …
// etc

@end

And you can just declare your IBActions on methods that you don't expose to the 
outside world entirely.
--
David Duncan

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Why so many public properties all up in my grizzle?

2012-03-16 Thread Brian Lambert
I’ve been developing iOS applications full-time for about 6 months now and
I love it. I feel pretty strong on the platform now.

I have a lingering question about something that’s really been bugging the
heck out of me, though, that I thought I would ask the list and get some
feedback on.

It seems to be the case that when people are developing a UIViewController
subclass or a UIView subclass that they expose *all* the implementation
details of that class through public properties vs. using ivars.

Here’s an example. For the purpose of this post, I’ve wrote a simple iPhone
app with one view. The link below is a screen shot of it:

https://s3.amazonaws.com/Softwarenerd/MyApp.jpg

For now, I used Interface Builder to generate the UI.  In doing so, I wound
up with:

#import 

// MyViewController interface.
@interface MyViewController : UIViewController

// Properties.
@property (weak, nonatomic) IBOutlet UILabel * labelMyLabel;

// buttonDoItTouchUpInside action.
- (IBAction)buttonDoItTouchUpInside:(id)sender;

@end

This means that my UILabel called labelMyLabel is publicly available.
Anyone who has access to an instance of MyViewController can do anything
they want to with my label, including replacing it.

Also, anyone who has an instance of MyViewController can call my
buttonDoItTouchUpInside action.

For example, in my AppDelegate, I can do:

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]
bounds]];

   MyViewController * myViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:nil];
   [self setMyViewController:myViewController];
   [[self window] setRootViewController:[self myViewController]];
   [[self window] makeKeyAndVisible];

   // Mess with MyViewController  HAHAHAHA FU, MyViewController
   [[myViewController labelMyLabel] setText:@"This is ridiculous"];
   return YES;
}

To me, this totally ridiculous. It breaks well-established rules of
encapsulation.

From my analysis, it appears to be nothing more than an artifact of how
rehydrating NIBs works, and it totally compromises good OO software design
by leaking all the implementation details of MyViewController to the
outside world.

Everyone, all the books, training materials, samples, and so on, just seem
to accept this style of doing things as being normal. In fact, one book I
read *encouraged* this technique of using public properties for ALL the
internal state of a class over using ivars. It said public properties were
preferable.

What in the world is the deal with this??  :-)  Can anyone explain this do
me?

Building this class without Interface builder, here’s how I coded it:

// MyViewController implementation.
@implementation MyViewController
{
@private
   UILabel * labelMyLabel_;
   UIButton * buttonDoIt_;
}

- (void)viewDidLoad
{
   [super viewDidLoad];

   [[self view] setBackgroundColor:[UIColor whiteColor]];

   labelMyLabel_ = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 20.0,
280.0, 21.0)];
   [labelMyLabel_ setText:@"I dare you to press Do It!"];
   [[self view] addSubview:labelMyLabel_];

   buttonDoIt_ = [UIButton buttonWithType:UIButtonTypeRoundedRect];
   [buttonDoIt_ setFrame:CGRectMake(20.0, 49.0, 72.0, 37.0)];
   [buttonDoIt_ setTitle:@"Do It" forState:UIControlStateNormal];
   [buttonDoIt_ addTarget:self action:@selector(buttonDoItTouchUpInside:)
forControlEvents:UIControlEventTouchUpInside];
   [[self view] addSubview:buttonDoIt_];
}

- (void)viewDidUnload
{
   [super viewDidUnload];
}

// buttonDoItTouchUpInside action.
- (void)buttonDoItTouchUpInside:(id)sender
{
   [labelMyLabel_ setText:@"You pressed Do It!"];
}

@end

To me, this is how things should be. The implementation details of how my
view works are hidden.

Am I missing something?

@property sure is convenient, but it seems to be misused a lot. A class
should expose properties that are public, and hide implementation details
that are not.

Thanks!

Brian
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com