|
I'm taking a beginner's course in Objective-C programming, so this is probably a really dumb question: I don't understand where I'm supposed to initialize my properties' values. Frankly, I'm too embarrassed to ask my teacher at this point. I keep getting "initializer element is not a compile-time constant", and I kind of get that I'm supposed to initialize a properties value elsewhere. I've worked with C# before, so I'm used to having a constructor, instance variables and stuff. E: As an example, say I need an NSArray with a couple of constant strings from which one is randomly selected when the user presses a button on screen. Where would I add the constant strings to the NSArray? It doesn't make sense to me to add them to it when the user presses the button. Bartie fucked around with this message at 18:17 on Oct 12, 2013 |
# ? Oct 12, 2013 17:37 |
|
|
# ? May 17, 2024 01:13 |
|
Bartie posted:I'm taking a beginner's course in Objective-C programming, so this is probably a really dumb question: I don't understand where I'm supposed to initialize my properties' values. Your error is because you are trying to initialize something as a static variable (a constant), but it is not compile-time determinable to be constant. In the most general case, you should initialize your instance variables and properties inside any of the - (id)init methods. Note that they are not dynamic methods, you have to be explicit in defining them. code:
UxP fucked around with this message at 18:26 on Oct 12, 2013 |
# ? Oct 12, 2013 18:23 |
|
I think I get it now! Thanks a ton, I really appreciate it!
|
# ? Oct 12, 2013 18:39 |
|
UxP posted:Anyone else at CocoaSlopes? Nope but what are the other good Cocoa/iOS related conferences, WWDC notwithstanding? Now that I'm doing this full time I need to get some more free trips to interesting places.
|
# ? Oct 12, 2013 19:12 |
|
UxP posted:Your error is because you are trying to initialize something as a static variable (a constant), but it is not compile-time determinable to be constant. You don't need @synthesize statements anymore. Properties are auto-synthesized, with the backing variable being named _myPropertyName. The only time you need a @synthesize statement is if the backing variable needs to be named something else.
|
# ? Oct 12, 2013 20:20 |
|
So wait, I learned (a while ago) that you had to do Objective-C code:
|
# ? Oct 12, 2013 20:32 |
|
Just 2. edit: that is, so long as you're compiling for the non-fragile ABI, aka distribution target is iOS or OS X 10.7 (I think you also have to be compiling for 64-bit-only on OS X) you can even do code:
To hide your non-property instance variables. Doc Block fucked around with this message at 20:43 on Oct 12, 2013 |
# ? Oct 12, 2013 20:34 |
|
Doc Block posted:You don't need @synthesize statements anymore. Properties are auto-synthesized, with the backing variable being named _myPropertyName. The only time you need a @synthesize statement is if the backing variable needs to be named something else. What if you want to use lazy instantiation? Or perhaps that's also deprecated?
|
# ? Oct 12, 2013 21:02 |
|
Doc Block posted:Just 2. Ok, this has thrown me. This is the way I've always approached it; removing internal variables from the header file (interface) and adding them as explicitly declared (underscore-prefixed) private variables in the implementation block. More recently I've been pushed towards removing the implementation-level declarations and instead including an unnamed category in the .m file, and declaring the variables as properties. What's the difference between these two approaches? Other than the default implementation for the property setter handling KVO for you (although I'd be surprised at a use-case where you had to observe for that internally within one object).
|
# ? Oct 13, 2013 01:27 |
|
Bartie posted:What if you want to use lazy instantiation? Or perhaps that's also deprecated? You can still do lazy instantiation, but then you do have to explicitly declare an ivar (you can still leave out the @synthesize statement). Objective-C code:
|
# ? Oct 13, 2013 03:01 |
|
You only have to explicitly declare an ivar if you replace both the default getter and setter.
|
# ? Oct 13, 2013 03:23 |
|
Froist posted:Ok, this has thrown me. This is the way I've always approached it; removing internal variables from the header file (interface) and adding them as explicitly declared (underscore-prefixed) private variables in the implementation block. More recently I've been pushed towards removing the implementation-level declarations and instead including an unnamed category in the .m file, and declaring the variables as properties. What's the difference between these two approaches? Other than the default implementation for the property setter handling KVO for you (although I'd be surprised at a use-case where you had to observe for that internally within one object). With ARC there is no reason to do this unless you're doing lazy instantiation. The reason people started doing the whole "make properties for all ivars and only access them via the property setter/getter, even within the object's code" is because, pre-ARC, using properties declared with retain and a synthesized setter & getter was an easy way to get ARC-like behavior, at the cost of doing a method call for each and every ivar access. ARC has completely eliminated the original reason for doing this, but it had already become The One True Way According To Somebody On The Internet (who was almost always a web programmer who recently started programming in Objective-C) and so even after everyone switched to ARC people still push it as the One True Way. As to declaring ivars in the header vs declaring them in the implementation, it used to be you had to declare them in the header. Something to do with the Objective-C's old ABI, if memory serves. You still have to do this (and use @sythesize statements) when compiling 32-bit OS X programs, which is why so many OS X developers have dropped support for 10.6 and only compile for 64-bit. rjmccall could probably provide more info.
|
# ? Oct 13, 2013 03:26 |
|
I thought the main benefit of always using setters / getters was to help out with KVO? If you set / access ivars directly the changes are not observed.
|
# ? Oct 13, 2013 03:55 |
|
lord funk posted:I thought the main benefit of always using setters / getters was to help out with KVO? If you set / access ivars directly the changes are not observed. The main advantage to always using the getters is that you don't have remember what properties have custom getters and get the occasional bug from not using the getter when you need to.
|
# ? Oct 13, 2013 04:01 |
|
Using the setters/getters inside the object's code for a publicly visible property is fine. But I'm talking about people creating a private category with properties for private ivars instead of just using ivars declared in the implementation. A lot of people apparently don't know you can declare ivars in a class's implementation now. Doc Block fucked around with this message at 05:24 on Oct 13, 2013 |
# ? Oct 13, 2013 05:20 |
|
The other benefits to using accessors for private data (e.g. a property declared in a class extension) are "copy" and (to a lesser extent) "atomic". You could make sure to assign a copy to your ivar anytime you set it, or just go through your accessor and forget about it. Speaking of KVO and KVC, is there an argument there supporting an ivar over a "private" property? You can turn off the automatic KVC ivar support, but not so much for a property. I think.
|
# ? Oct 13, 2013 05:48 |
|
pokeyman posted:The other benefits to using accessors for private data (e.g. a property declared in a class extension) are "copy" and (to a lesser extent) "atomic". You could make sure to assign a copy to your ivar anytime you set it, or just go through your accessor and forget about it. * IIRC ivars won't have their symbols compiled in, whereas a property must be accessible as such. * KVO is a powerful and useful tool to avoid when not necessary, i.e. when adding a delegate would add unnecessary protocol bloat, when adding a blocks API is incongruous, or when it involves observing/unobserving a large number of objects or properties (the former for performance and the latter for maintainability). * The cost argument doesn't really matter for NSObjects. * If you need to copy, you can do it manually. You don't get the 'copy' for free, true, and while this is a compelling counterargument to me, in practice even in large codebases this isn't much of an issue, and bugs rarely pop up unless there was misuse of a NSMutableString, which is often easily remedied by just finding uses of that string and copying them. * You can set a breakpoint on a private property. * You can set custom setters/getters for an API that feels slightly more natural, i.e. with getter=isHidden, .hidden = YES or blah.isHidden. * If you implement a category on a collection i.e. -(NSArray *)arrayWithSelector:(SEL)aSelector; then you can use a functional programming style to transform one set of objects into, say, an array of one of their properties. Even though I actually side slightly on the side of internal properties, there's nothing wrong with ivars (it's used often at work) and no significant advantages either way. The details are largely subjective and searching for the "truth" converges to bikeshedding, in my experience. Fun fact: Apps on the 5S are potentially more liable to fall victim to the OOM killer than on the 5. As a 64-bit device running 32-bit apps, the 5S will have 32-bit system libraries in memory alongside the 64-bit ones. These libraries can be pretty huge, but they're not loaded per-application. Also, since the 5S has 1GB of virtual address space vs. the 5's 2...add up the system libraries, and map in some fonts, images, and other data, and boom - OOM killed.
|
# ? Oct 13, 2013 07:05 |
|
Doc Block posted:You don't need @synthesize statements anymore. Properties are auto-synthesized, with the backing variable being named _myPropertyName. The only time you need a @synthesize statement is if the backing variable needs to be named something else. Yeah, I was debating wether or not to state something about that in the post. I was teaching a co-worker about Objective-C a couple weeks ago and it really tripped him up that properties were auto-synthesized when all the code he wrote a couple years ago would complain loudly about properties not being synthesized, so I decided to include it just so it was more verbose.
|
# ? Oct 13, 2013 17:48 |
|
Doctor w-rw-rw- posted:* IIRC ivars won't have their symbols compiled in, whereas a property must be accessible as such. * Though you can trivially ask the runtime to list a class's ivars and retrieve an object's ivar's values. (Or, if you're using a fragile runtime, you look at the header and offset some pointers.) * Not sure what "unnecessary protocol bloat" means. Dealing with KVO (adding and removing observers plus implementing -observeValueOfKeyPath:… properly) takes me about as much code and brain power as a delegate protocol. * What cost argument? * Having objects mutate out from under you may not be a common bug but it's a pain to track down. And sending -copy to an immutable instance just returns itself. * You can set a watchpoint on an ivar (maybe not as easily as a breakpoint on a property). * Not sure what renaming the accessors matters, you can do that with properties or with your own accessors and it's a non-issue with ivars. * Presumably if you're going to the work of hiding your ivar and disabling automatic KVC support then you don't want someone plucking that value out using a collection operator. If you're not disabling automatic KVC then that's a pretty bad example as -valueForKey: is universally overridden to do exactly that and works with ivars, properties, and methods. quote:Even though I actually side slightly on the side of internal properties, there's nothing wrong with ivars (it's used often at work) and no significant advantages either way. The details are largely subjective and searching for the "truth" converges to bikeshedding, in my experience. I'm inclined to agree. I wish there was some smoking gun, even a rare scenario, where you can just say "look, always do it this way and you never have an issue". But I can't think of one. ivar versus property seems like a tie. Ties go to the style guide
|
# ? Oct 13, 2013 20:37 |
|
Is it possible to have separate icon(s) for iOS 7+?
|
# ? Oct 13, 2013 20:40 |
|
Small White Dragon posted:Is it possible to have separate icon(s) for iOS 7+? App icons? I think an Asset Catalog will allow separates. Dunno if you can do it with Info.plist.
|
# ? Oct 13, 2013 20:41 |
|
Pretty sure you can, even without asset catalogs. Especially since iOS 6.1 and earlier didn't support asset catalogs.
|
# ? Oct 13, 2013 20:45 |
|
I'm sure you guys have seen this before, but it was new to me: http://fuckingblocksyntax.com
|
# ? Oct 14, 2013 05:38 |
|
Doc Block posted:I'm sure you guys have seen this before, but it was new to me: http://fuckingblocksyntax.com This was also an interesting read to me, at least in terms of making you think a little on "why" the syntax is that way. http://nilsou.com/blog/2013/08/21/objective-c-blocks-syntax/
|
# ? Oct 14, 2013 06:02 |
|
pokeyman posted:I'm inclined to agree. I wish there was some smoking gun, even a rare scenario, where you can just say "look, always do it this way and you never have an issue". But I can't think of one. ivar versus property seems like a tie. Ties go to the style guide BTW, I was presenting reasons I heard, not necessarily standing by them. Also, I was sloppy in editing and forgot to remove the "cost argument" bullet point as it was referring to something I deleted about Core Data, and didn't realize that ivar info was compiled in (but on reflection, of course it is). Doctor w-rw-rw- fucked around with this message at 07:01 on Oct 14, 2013 |
# ? Oct 14, 2013 06:57 |
|
Has anyone ever experienced different behavior when running an app on the simulator vs an actual device? I have a small app that loads models and lets you apply different shaders, but for some reason the specular looks hatched out when I run the app on my iPad. Simulator (The correct way this should look) iPad http://imgur.com/WHYlSeI,FxfzMKs#1 (Image is huge and I dont want to break h-scroll) Apologies in advance if this is more of a graphics megathread question. Aesion fucked around with this message at 08:00 on Oct 14, 2013 |
# ? Oct 14, 2013 07:57 |
|
I don't have the relevant knowledge to answer your actual question butAesion posted:Has anyone ever experienced different behavior when running an app on the simulator vs an actual device? Yes, absolutely.
|
# ? Oct 14, 2013 08:16 |
|
Aesion posted:Has anyone ever experienced different behavior when running an app on the simulator vs an actual device? If I had to guess, I'd say it's a precision issue, or something similar. And yeah, the simulator is not an emulator so differences do happen.
|
# ? Oct 14, 2013 08:20 |
|
Yeah the simulator can be quite different, especially once you get into shaders and what is actually supported by the device hardware. It does look possibly like a precision thing perhaps on the fragment coords? Also check whatever filtering you think is on is really on.
|
# ? Oct 14, 2013 13:09 |
|
Your infrequently scheduled PSA for this week: If you aren't reading NSHipster, you should be. http://nshipster.com/nserror/ http://nshipster.com/key-value-observing/ http://nshipster.com/nspredicate/ http://nshipster.com/nsexpression/ http://nshipster.com/search-kit/ http://nshipster.com/at-compiler-directives/ There are so many more. Go read them. I also recommend reading Mike Ash' previous blog entries for the past few years: http://www.mikeash.com/pyblog/ Although Greg Parker only blogs once a year at the spring equinox, his posts are pure gold: http://www.sealiesoftware.com/blog/index.html
|
# ? Oct 14, 2013 16:46 |
|
Ender.uNF posted:Your infrequently scheduled PSA for this week: If you aren't reading NSHipster, you should be. And if you like those pieces, then buy his upcoming book so he writes more.
|
# ? Oct 14, 2013 19:07 |
|
I'm validating my app for the store (and loving xcode keeps on crashing when I try to use xcode as opposed to application loader to validate it? anyway...) and it's saying I"ve used non-public apis:quote:The app references non-public apis in Payload/Appname.app/Appname: However, I've not used that method at all, and I'm not sure what similar methods or APIs I might have used to irritate the validator. Any suggestions for how to track down whatever wrong API i've used in my code?
|
# ? Oct 14, 2013 19:51 |
|
Mr SuperAwesome posted:Any suggestions for how to track down whatever wrong API i've used in my code? Or don't. I got one of those messages for accessing a non-public property 'tags' which I did not have anywhere in my project. I wrote a note to the Apple reviewers and the app sailed through. Here's a (surprise surprise) iOS 7 change that's hosed up my app: my method of overriding UISlider is broken. I have a subclass which tests for a user touch, and if it's in the slider's bounds, sets the value to that point. It's so you can touch a slider anywhere to start dragging. code:
|
# ? Oct 14, 2013 19:56 |
|
lord funk posted:Or don't. I got one of those messages for accessing a non-public property 'tags' which I did not have anywhere in my project. I wrote a note to the Apple reviewers and the app sailed through. E: does modifiying layers directly count as a non-public API? e.g. code:
Mr SuperAwesome fucked around with this message at 20:15 on Oct 14, 2013 |
# ? Oct 14, 2013 20:12 |
|
Mr SuperAwesome posted:E: does modifiying layers directly count as a non-public API? I don't think so, but just a style note - I'd write that as: code:
|
# ? Oct 14, 2013 20:44 |
|
ah thanks for the tips. Apple's review guys got back to me very quickly, I was just braindead and forgot to take out the Reveal framework from my frameworks (which owns btw, excellent tool for UI stuff). Mr SuperAwesome fucked around with this message at 20:54 on Oct 14, 2013 |
# ? Oct 14, 2013 20:50 |
|
My most recent update had the validator screaming that I was using private API for using the Xcode-generated CoreData collection accessors on my own model classes. Something seems to have sent it off the rails.
|
# ? Oct 14, 2013 21:18 |
|
lord funk posted:Or don't. I got one of those messages for accessing a non-public property 'tags' which I did not have anywhere in my project. I wrote a note to the Apple reviewers and the app sailed through. Can you add a UIPanGestureRecognizer to an appropriate view and adjust the slider's value from there?
|
# ? Oct 14, 2013 21:26 |
|
Ender.uNF posted:My most recent update had the validator screaming that I was using private API for using the Xcode-generated CoreData collection accessors on my own model classes. Something seems to have sent it off the rails. There are a few names on some blacklist that can trigger this. I think naming a property `id` is one of them.
|
# ? Oct 14, 2013 21:29 |
|
|
# ? May 17, 2024 01:13 |
|
pokeyman posted:Can you add a UIPanGestureRecognizer to an appropriate view and adjust the slider's value from there? This is the best way forward. It's code that I can't wait to shred (the replacement is already done for another app) but too much work to purge it right now. Band-aid ahoy!
|
# ? Oct 14, 2013 22:01 |