Asked  11 Months ago    Answers:  5   Viewed   182 times

When is self needed for class properties? For example:

self.MyProperty = @"hi there";

vs

MyProperty = @"hi there";

MyProperty is an NSString set as (nonatomic, copy). Is there any difference in memory management for the above two?

What about when there is no property and the variable MyProperty is declared in the header file? Is a property needed if it is never referenced outside of the class? Does it make a difference to memory management?

 Answers

3

Yes, there is a difference for both memory and performance.

MyProperty = @"hi there";

This is considered a direct assignment. There is practically no memory or performance impact. Of course, that's not to say it's best practice - that's a different question :)

@property(nonatomic, copy) NSString *MyProperty;
// ...
self.MyProperty = @"hi there";

This statement has a significant impact on memory and performance. This is essentially equivalent to:

-(void)setMyProperty(NSString *)newValue {
    if (MyProperty != newValue) {
        [MyProperty release];
        MyProperty = [newValue copy];
    }
}

The old value is released and the new value is copied into MyProperty. This is acceptable and especially typical when dealing with strings when the string your assigning is mutable (ie, it could change later).

If, as in your example, you're simply assigning a static string (@"hi there"), there is nothing wrong with directly assigning the string value; it's more efficient however the difference in performance is trivial.

You can declare a property with @property as retain, copy, or assign (default is assign). You can then generate "accessor" (getter/setter) methods by using @synthesize. Here is what the setter methods look like that are generated when you do so:

// @property(nonatomic, assign)
-(void)setMyProperty(NSString *)newValue {
    MyProperty = newValue;
}

// @property(nonatomic, retain)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue retain];
    }

// @property(nonatomic, copy)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue copy];
    }
}

More information on ObjectiveC Declared Properties.

"You can use the @synthesize and @dynamic directives in @implementation blocks to trigger specific compiler actions. Note that neither is required for any given @property declaration.

Important: If you do not specify either @synthesize or @dynamic for a particular property, you must provide a getter and setter (or just a getter in the case of a readonly property) method implementation for that property."

In other words, if you declare a property but don't synthesize the property, you won't be able to use [self MyProperty] or self.MyProperty unless you define 'MyProperty' and 'setMyProperty' methods. If you don't declare a property then you simply have an instance variable.

Note: @dynamic doesn't generate the accessors. It's really used if you're dynamically (ie, magically) resolving accessor methods via loading code or dynamic method resolution.

Saturday, July 3, 2021
 
Vlad
 
3

Short Answer

Use $this to refer to the current object. Use self to refer to the current class. In other words, use $this->member for non-static members, use self::$member for static members.

Full Answer

Here is an example of correct usage of $this and self for non-static and static member variables:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

Here is an example of incorrect usage of $this and self for non-static and static member variables:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

Here is an example of polymorphism with $this for member functions:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

Here is an example of suppressing polymorphic behaviour by using self for member functions:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

The idea is that $this->foo() calls the foo() member function of whatever is the exact type of the current object. If the object is of type X, it thus calls X::foo(). If the object is of type Y, it calls Y::foo(). But with self::foo(), X::foo() is always called.

From http://www.phpbuilder.com/board/showthread.php?t=10354489:

By http://board.phpbuilder.com/member.php?145249-laserlight

Thursday, April 1, 2021
 
3

When you're doing an action on the instance that's calling the method, you use self.

With this code

class SocialData < ActiveRecord::Base
  def set_active_flag(val)
    active_flag = val
    save!
  end
end

You are defining a brand new scoped local variable called active_flag, setting it to the passed in value, it's not associated with anything, so it's promptly thrown away when the method ends like it never existed.

self.active_flag = val

However tells the instance to modify its own attribute called active_flag, instead of a brand new variable. That's why it works.

Saturday, July 31, 2021
 
1

C++ is Bjarne Stroustroup's language based on adding classes and metaprogramming to C in such a way that puts most additional work into the compiler, and relies on least possible effort at runtime.

Objective-C is Brad Cox's language based on adding a SmallTalk-style dynamic message-passing runtime library to C, with a small amount of syntax addition to make it easier to use.

Objective-C++ is, to put it bluntly, what you get when you add the Objective-C runtime and syntax to C++. It has its limitations (e.g. you can't create an Objective-C subclass of a C++ class or vice versa, and Objective-C doesn't like C++ namespaces) but allows you to use C++ classes from Objective-C objects and vice versa.

You can use Objective-C++ in iPhone development. What this means practically is that you could write an application whose object model was entirely C++, where the controller layer would need to interface to Objective-C in order to use the Cocoa Touch APIs.

Wednesday, September 8, 2021
 
2

I found a solution by noting that there was an existing wrapper class CWrapper.h and it was an objective-C++ implementation class CWrapper.mm. There was a CMain variable instantiated as cmain. I made a getter method for x and I simply created a static method in the wrapper class + (void) passX:(int) number; that I called in the slider class. I chose a static method because this for this application, this value will never have to be different between objects. I hope I made the right choice here!

See code changes below:

I added this to the Slider.h file.

- (int)X;

I added the getter and [CWrapper passX:[self getX]]; to the updateSliderValue method in the Slider.mm file.

- (int)X {
    return [slider intValue];
}

- (IBAction)updateSliderValue:(id)sender {
    [sliderValue setIntValue:[slider intValue]];
    [CWrapper passX:[self getX]];
}

This is the code I added to CWrapper.h.

+ (void) passX:(int) number;

This is the code I added to CWrapper.mm.

+ (void) passX:(int)num
{
    cmain.setValueofX(num);
}
Wednesday, October 27, 2021
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :